<filename>tests/commands/test_runner.py
#!/usr/bin/env python
import os

import subprocess
import unittest

from nose.tools import ok_

from ..util import inject_sitecustomize


class DdtraceRunTest(unittest.TestCase):
    def tearDown(self):
        """
        Clear DATADOG_* env vars between tests
        """
        keys = (
            'DATADOG_ENV',
            'DATADOG_TRACE_ENABLED',
            'DATADOG_SERVICE_NAME',
            'DATADOG_TRACE_DEBUG',
            'DD_TRACE_GLOBAL_TAGS',
            'DD_LOGS_INJECTION',
        )
        for k in keys:
            if k in os.environ:
                del os.environ[k]

    def test_service_name_passthrough(self):
        """
        $DATADOG_SERVICE_NAME gets passed through to the program
        """
        os.environ["DATADOG_SERVICE_NAME"] = "my_test_service"

        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_service.py']
        )
        assert out.startswith(b"Test success")

    def test_env_name_passthrough(self):
        """
        $DATADOG_ENV gets passed through to the global tracer as an 'env' tag
        """
        os.environ["DATADOG_ENV"] = "test"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_env.py']
        )
        assert out.startswith(b"Test success")

    def test_env_enabling(self):
        """
        DATADOG_TRACE_ENABLED=false allows disabling of the global tracer
        """
        os.environ["DATADOG_TRACE_ENABLED"] = "false"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_disabled.py']
        )
        assert out.startswith(b"Test success")

        os.environ["DATADOG_TRACE_ENABLED"] = "true"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_enabled.py']
        )
        assert out.startswith(b"Test success")

    def test_patched_modules(self):
        """
        Using `ddtrace-run` registers some generic patched modules
        """
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_patched_modules.py']
        )
        assert out.startswith(b"Test success")

    def test_integration(self):
        out = subprocess.check_output(
            ['ddtrace-run', 'python', '-m', 'tests.commands.ddtrace_run_integration']
        )
        assert out.startswith(b"Test success")

    def test_debug_enabling(self):
        """
        DATADOG_TRACE_DEBUG=true allows setting debug_logging of the global tracer
        """
        os.environ["DATADOG_TRACE_DEBUG"] = "false"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_no_debug.py']
        )
        assert out.startswith(b"Test success")

        os.environ["DATADOG_TRACE_DEBUG"] = "true"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_debug.py']
        )
        assert out.startswith(b"Test success")

    def test_host_port_from_env(self):
        """
        DATADOG_TRACE_AGENT_HOSTNAME|PORT point to the tracer
        to the correct host/port for submission
        """
        os.environ["DATADOG_TRACE_AGENT_HOSTNAME"] = "172.16.31.10"
        os.environ["DATADOG_TRACE_AGENT_PORT"] = "8120"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_hostname.py']
        )
        assert out.startswith(b"Test success")

    def test_host_port_from_env_dd(self):
        """
        DD_AGENT_HOST|DD_TRACE_AGENT_PORT point to the tracer
        to the correct host/port for submission
        """
        os.environ['DD_AGENT_HOST'] = '172.16.31.10'
        os.environ['DD_TRACE_AGENT_PORT'] = '8120'
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_hostname.py']
        )
        assert out.startswith(b'Test success')

        # Do we get the same results without `ddtrace-run`?
        out = subprocess.check_output(
            ['python', 'tests/commands/ddtrace_run_hostname.py']
        )
        assert out.startswith(b'Test success')

    def test_priority_sampling_from_env(self):
        """
        DATADOG_PRIORITY_SAMPLING enables Distributed Sampling
        """
        os.environ["DATADOG_PRIORITY_SAMPLING"] = "True"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_priority_sampling.py']
        )
        assert out.startswith(b"Test success")

    def test_patch_modules_from_env(self):
        """
        DATADOG_PATCH_MODULES overrides the defaults for patch_all()
        """
        from ddtrace.bootstrap.sitecustomize import EXTRA_PATCHED_MODULES, update_patched_modules
        orig = EXTRA_PATCHED_MODULES.copy()

        # empty / malformed strings are no-ops
        os.environ["DATADOG_PATCH_MODULES"] = ""
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        os.environ["DATADOG_PATCH_MODULES"] = ":"
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        os.environ["DATADOG_PATCH_MODULES"] = ","
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        os.environ["DATADOG_PATCH_MODULES"] = ",:"
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        # overrides work in either direction
        os.environ["DATADOG_PATCH_MODULES"] = "django:false"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["django"] is False

        os.environ["DATADOG_PATCH_MODULES"] = "boto:true"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["boto"] is True

        os.environ["DATADOG_PATCH_MODULES"] = "django:true,boto:false"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["boto"] is False
        assert EXTRA_PATCHED_MODULES["django"] is True

        os.environ["DATADOG_PATCH_MODULES"] = "django:false,boto:true"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["boto"] is True
        assert EXTRA_PATCHED_MODULES["django"] is False

    def test_sitecustomize_without_ddtrace_run_command(self):
        # [Regression test]: ensure `sitecustomize` path is removed only if it's
        # present otherwise it will cause:
        #   ValueError: list.remove(x): x not in list
        # as mentioned here: https://github.com/DataDog/dd-trace-py/pull/516
        env = inject_sitecustomize('')
        out = subprocess.check_output(
            ['python', 'tests/commands/ddtrace_minimal.py'],
            env=env,
        )
        # `out` contains the `loaded` status of the module
        result = out[:-1] == b'True'
        ok_(result)

    def test_sitecustomize_run(self):
        # [Regression test]: ensure users `sitecustomize.py` is properly loaded,
        # so that our `bootstrap/sitecustomize.py` doesn't override the one
        # defined in users' PYTHONPATH.
        env = inject_sitecustomize('tests/commands/bootstrap')
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_sitecustomize.py'],
            env=env,
        )
        assert out.startswith(b"Test success")

    def test_sitecustomize_run_suppressed(self):
        # ensure `sitecustomize.py` is not loaded if `-S` is used
        env = inject_sitecustomize('tests/commands/bootstrap')
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_sitecustomize.py', '-S'],
            env=env,
        )
        assert out.startswith(b"Test success")

    def test_argv_passed(self):
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_argv.py', 'foo', 'bar']
        )
        assert out.startswith(b"Test success")

    def test_got_app_name(self):
        """
        apps run with ddtrace-run have a proper app name
        """
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_app_name.py']
        )
        assert out.startswith(b"ddtrace_run_app_name.py")

    def test_global_trace_tags(self):
        """ Ensure global tags are passed in from environment
        """
        os.environ["DD_TRACE_GLOBAL_TAGS"] = 'a:True,b:0,c:C'

        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_global_tags.py']
        )
        assert out.startswith(b"Test success")

    def test_logs_injection(self):
        """ Ensure logs injection works
        """

        os.environ['DD_LOGS_INJECTION'] = 'true'

        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_logs_injection.py']
        )
        assert out.startswith(b"Test success")

<filename>tests/commands/test_runner.py
#!/usr/bin/env python
import os

import subprocess
import unittest

from nose.tools import ok_

from ..util import inject_sitecustomize


class DdtraceRunTest(unittest.TestCase):
    def tearDown(self):
        """
        Clear DATADOG_* env vars between tests
        """
        keys = (
            'DATADOG_ENV',
            'DATADOG_TRACE_ENABLED',
            'DATADOG_SERVICE_NAME',
            'DATADOG_TRACE_DEBUG',
            'DD_TRACE_GLOBAL_TAGS',
            'DD_LOGS_INJECTION',
        )
        for k in keys:
            if k in os.environ:
                del os.environ[k]

    def test_service_name_passthrough(self):
        """
        $DATADOG_SERVICE_NAME gets passed through to the program
        """
        os.environ["DATADOG_SERVICE_NAME"] = "my_test_service"

        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_service.py']
        )
        assert out.startswith(b"Test success")

    def test_env_name_passthrough(self):
        """
        $DATADOG_ENV gets passed through to the global tracer as an 'env' tag
        """
        os.environ["DATADOG_ENV"] = "test"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_env.py']
        )
        assert out.startswith(b"Test success")

    def test_env_enabling(self):
        """
        DATADOG_TRACE_ENABLED=false allows disabling of the global tracer
        """
        os.environ["DATADOG_TRACE_ENABLED"] = "false"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_disabled.py']
        )
        assert out.startswith(b"Test success")

        os.environ["DATADOG_TRACE_ENABLED"] = "true"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_enabled.py']
        )
        assert out.startswith(b"Test success")

    def test_patched_modules(self):
        """
        Using `ddtrace-run` registers some generic patched modules
        """
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_patched_modules.py']
        )
        assert out.startswith(b"Test success")

    def test_integration(self):
        out = subprocess.check_output(
            ['ddtrace-run', 'python', '-m', 'tests.commands.ddtrace_run_integration']
        )
        assert out.startswith(b"Test success")

    def test_debug_enabling(self):
        """
        DATADOG_TRACE_DEBUG=true allows setting debug_logging of the global tracer
        """
        os.environ["DATADOG_TRACE_DEBUG"] = "false"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_no_debug.py']
        )
        assert out.startswith(b"Test success")

        os.environ["DATADOG_TRACE_DEBUG"] = "true"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_debug.py']
        )
        assert out.startswith(b"Test success")

    def test_host_port_from_env(self):
        """
        DATADOG_TRACE_AGENT_HOSTNAME|PORT point to the tracer
        to the correct host/port for submission
        """
        os.environ["DATADOG_TRACE_AGENT_HOSTNAME"] = "172.16.31.10"
        os.environ["DATADOG_TRACE_AGENT_PORT"] = "8120"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_hostname.py']
        )
        assert out.startswith(b"Test success")

    def test_host_port_from_env_dd(self):
        """
        DD_AGENT_HOST|DD_TRACE_AGENT_PORT point to the tracer
        to the correct host/port for submission
        """
        os.environ['DD_AGENT_HOST'] = '172.16.31.10'
        os.environ['DD_TRACE_AGENT_PORT'] = '8120'
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_hostname.py']
        )
        assert out.startswith(b'Test success')

        # Do we get the same results without `ddtrace-run`?
        out = subprocess.check_output(
            ['python', 'tests/commands/ddtrace_run_hostname.py']
        )
        assert out.startswith(b'Test success')

    def test_priority_sampling_from_env(self):
        """
        DATADOG_PRIORITY_SAMPLING enables Distributed Sampling
        """
        os.environ["DATADOG_PRIORITY_SAMPLING"] = "True"
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_priority_sampling.py']
        )
        assert out.startswith(b"Test success")

    def test_patch_modules_from_env(self):
        """
        DATADOG_PATCH_MODULES overrides the defaults for patch_all()
        """
        from ddtrace.bootstrap.sitecustomize import EXTRA_PATCHED_MODULES, update_patched_modules
        orig = EXTRA_PATCHED_MODULES.copy()

        # empty / malformed strings are no-ops
        os.environ["DATADOG_PATCH_MODULES"] = ""
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        os.environ["DATADOG_PATCH_MODULES"] = ":"
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        os.environ["DATADOG_PATCH_MODULES"] = ","
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        os.environ["DATADOG_PATCH_MODULES"] = ",:"
        update_patched_modules()
        assert orig == EXTRA_PATCHED_MODULES

        # overrides work in either direction
        os.environ["DATADOG_PATCH_MODULES"] = "django:false"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["django"] is False

        os.environ["DATADOG_PATCH_MODULES"] = "boto:true"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["boto"] is True

        os.environ["DATADOG_PATCH_MODULES"] = "django:true,boto:false"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["boto"] is False
        assert EXTRA_PATCHED_MODULES["django"] is True

        os.environ["DATADOG_PATCH_MODULES"] = "django:false,boto:true"
        update_patched_modules()
        assert EXTRA_PATCHED_MODULES["boto"] is True
        assert EXTRA_PATCHED_MODULES["django"] is False

    def test_sitecustomize_without_ddtrace_run_command(self):
        # [Regression test]: ensure `sitecustomize` path is removed only if it's
        # present otherwise it will cause:
        #   ValueError: list.remove(x): x not in list
        # as mentioned here: https://github.com/DataDog/dd-trace-py/pull/516
        env = inject_sitecustomize('')
        out = subprocess.check_output(
            ['python', 'tests/commands/ddtrace_minimal.py'],
            env=env,
        )
        # `out` contains the `loaded` status of the module
        result = out[:-1] == b'True'
        ok_(result)

    def test_sitecustomize_run(self):
        # [Regression test]: ensure users `sitecustomize.py` is properly loaded,
        # so that our `bootstrap/sitecustomize.py` doesn't override the one
        # defined in users' PYTHONPATH.
        env = inject_sitecustomize('tests/commands/bootstrap')
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_sitecustomize.py'],
            env=env,
        )
        assert out.startswith(b"Test success")

    def test_sitecustomize_run_suppressed(self):
        # ensure `sitecustomize.py` is not loaded if `-S` is used
        env = inject_sitecustomize('tests/commands/bootstrap')
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_sitecustomize.py', '-S'],
            env=env,
        )
        assert out.startswith(b"Test success")

    def test_argv_passed(self):
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_argv.py', 'foo', 'bar']
        )
        assert out.startswith(b"Test success")

    def test_got_app_name(self):
        """
        apps run with ddtrace-run have a proper app name
        """
        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_app_name.py']
        )
        assert out.startswith(b"ddtrace_run_app_name.py")

    def test_global_trace_tags(self):
        """ Ensure global tags are passed in from environment
        """
        os.environ["DD_TRACE_GLOBAL_TAGS"] = 'a:True,b:0,c:C'

        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_global_tags.py']
        )
        assert out.startswith(b"Test success")

    def test_logs_injection(self):
        """ Ensure logs injection works
        """

        os.environ['DD_LOGS_INJECTION'] = 'true'

        out = subprocess.check_output(
            ['ddtrace-run', 'python', 'tests/commands/ddtrace_run_logs_injection.py']
        )
        assert out.startswith(b"Test success")

#!/usr/bin/env python Clear DATADOG_* env vars between tests $DATADOG_SERVICE_NAME gets passed through to the program $DATADOG_ENV gets passed through to the global tracer as an 'env' tag DATADOG_TRACE_ENABLED=false allows disabling of the global tracer Using `ddtrace-run` registers some generic patched modules DATADOG_TRACE_DEBUG=true allows setting debug_logging of the global tracer DATADOG_TRACE_AGENT_HOSTNAME|PORT point to the tracer         to the correct host/port for submission DD_AGENT_HOST|DD_TRACE_AGENT_PORT point to the tracer         to the correct host/port for submission # Do we get the same results without `ddtrace-run`? DATADOG_PRIORITY_SAMPLING enables Distributed Sampling DATADOG_PATCH_MODULES overrides the defaults for patch_all() # empty / malformed strings are no-ops # overrides work in either direction # [Regression test]: ensure `sitecustomize` path is removed only if it's # present otherwise it will cause: #   ValueError: list.remove(x): x not in list # as mentioned here: https://github.com/DataDog/dd-trace-py/pull/516 # `out` contains the `loaded` status of the module # [Regression test]: ensure users `sitecustomize.py` is properly loaded, # so that our `bootstrap/sitecustomize.py` doesn't override the one # defined in users' PYTHONPATH. # ensure `sitecustomize.py` is not loaded if `-S` is used apps run with ddtrace-run have a proper app name Ensure global tags are passed in from environment Ensure logs injection works