Esempio n. 1
0
    def test_simple_cache_add(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        cache.add(u"á_complex_number", 50)
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "add")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 0)

        expected_meta = {
            "flask_cache.key": u"á_complex_number",
            "flask_cache.backend": "simple",
        }

        eq_(span.meta, expected_meta)
Esempio n. 2
0
    def test_simple_cache_set_many(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        cache.set_many({
            'first_complex_op': 10,
            'second_complex_op': 20,
        })
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "set_many")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 0)

        eq_(span.meta["flask_cache.backend"], "simple")
        ok_("first_complex_op" in span.meta["flask_cache.key"])
        ok_("second_complex_op" in span.meta["flask_cache.key"])
Esempio n. 3
0
def test_tracer_wrap_class():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    class Foo(object):

        @staticmethod
        @tracer.wrap()
        def s():
            return 1

        @classmethod
        @tracer.wrap()
        def c(cls):
            return 2

        @tracer.wrap()
        def i(cls):
            return 3

    f = Foo()
    eq_(f.s(), 1)
    eq_(f.c(), 2)
    eq_(f.i(), 3)

    spans = writer.pop()
    eq_(len(spans), 3)
    names = [s.name for s in spans]
    # FIXME[matt] include the class name here.
    eq_(sorted(names), sorted(["tests.test_tracer.%s" % n for n in ["s", "c", "i"]]))
Esempio n. 4
0
    def test_cache_add_without_arguments(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        # make a wrong call
        with assert_raises(TypeError) as ex:
            cache.add()

        # ensure that the error is not caused by our tracer
        ok_("add()" in ex.exception.args[0])
        ok_("argument" in ex.exception.args[0])
        spans = writer.pop()
        # an error trace must be sent
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "add")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 1)
Esempio n. 5
0
    def test_memcached_cache_tracing_with_a_wrong_connection(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        config = {
            "CACHE_TYPE": "memcached",
            "CACHE_MEMCACHED_SERVERS": ['localhost:22230'],
        }
        cache = Cache(app, config=config)

        # use a wrong memcached connection
        try:
            cache.get(u"á_complex_operation")
        except Exception:
            pass

        # ensure that the error is not caused by our tracer
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "get")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.meta[CACHE_BACKEND], "memcached")
        eq_(span.meta[net.TARGET_HOST], 'localhost')
        eq_(span.meta[net.TARGET_PORT], '22230')
Esempio n. 6
0
    def test_simple_cache_add(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        cache.add(u"á_complex_number", 50)
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "add")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 0)

        expected_meta = {
            "flask_cache.key": u"á_complex_number",
            "flask_cache.backend": "simple",
        }

        assert_dict_issuperset(span.meta, expected_meta)
    def test_redis_cache_tracing_with_a_wrong_connection(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        config = {
            'CACHE_TYPE': 'redis',
            'CACHE_REDIS_PORT': 2230,
            'CACHE_REDIS_HOST': '127.0.0.1'
        }
        cache = Cache(app, config=config)

        # use a wrong redis connection
        with pytest.raises(ConnectionError) as ex:
            cache.get(u'á_complex_operation')

        # ensure that the error is not caused by our tracer
        assert '127.0.0.1:2230. Connection refused.' in ex.value.args[0]
        spans = writer.pop()
        # an error trace must be sent
        assert len(spans) == 1
        span = spans[0]
        assert span.service == self.SERVICE
        assert span.resource == 'get'
        assert span.name == 'flask_cache.cmd'
        assert span.span_type == 'cache'
        assert span.meta[CACHE_BACKEND] == 'redis'
        assert span.meta[net.TARGET_HOST] == '127.0.0.1'
        assert span.metrics[net.TARGET_PORT] == 2230
        assert span.error == 1
Esempio n. 8
0
def test_tracer_wrap_factory():
    # it should use a wrap_factory if defined
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    def wrap_executor(tracer,
                      fn,
                      args,
                      kwargs,
                      span_name=None,
                      service=None,
                      resource=None,
                      span_type=None):
        with tracer.trace('wrap.overwrite') as span:
            span.set_tag('args', args)
            span.set_tag('kwargs', kwargs)
            return fn(*args, **kwargs)

    @tracer.wrap()
    def wrapped_function(param, kw_param=None):
        eq_(42, param)
        eq_(42, kw_param)

    # set the custom wrap factory after the wrapper has been called
    tracer.configure(wrap_executor=wrap_executor)

    # call the function expecting that the custom tracing wrapper is used
    wrapped_function(42, kw_param=42)
    eq_(writer.spans[0].name, 'wrap.overwrite')
    eq_(writer.spans[0].get_tag('args'), '(42,)')
    eq_(writer.spans[0].get_tag('kwargs'), '{\'kw_param\': 42}')
Esempio n. 9
0
    def test_simple_cache_set(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        cache.set(u"á_complex_operation", u"with_á_value\nin two lines")
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "set")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 0)

        expected_meta = {
            "flask_cache.key": u"á_complex_operation",
            "flask_cache.backend": "simple",
        }

        assert_dict_issuperset(span.meta, expected_meta)
Esempio n. 10
0
    def test_redis_cache_tracing_with_a_wrong_connection(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        config = {
            "CACHE_TYPE": "redis",
            "CACHE_REDIS_PORT": 2230,
            "CACHE_REDIS_HOST": "127.0.0.1"
        }
        cache = Cache(app, config=config)

        # use a wrong redis connection
        with assert_raises(ConnectionError) as ex:
            cache.get(u"á_complex_operation")

        print(ex.exception)
        # ensure that the error is not caused by our tracer
        ok_("127.0.0.1:2230. Connection refused." in ex.exception.args[0])
        spans = writer.pop()
        # an error trace must be sent
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "get")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.meta[CACHE_BACKEND], "redis")
        eq_(span.meta[net.TARGET_HOST], '127.0.0.1')
        eq_(span.meta[net.TARGET_PORT], '2230')
        eq_(span.error, 1)
Esempio n. 11
0
    def test_memcached_cache_tracing_with_a_wrong_connection(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        config = {
            "CACHE_TYPE": "memcached",
            "CACHE_MEMCACHED_SERVERS": ['localhost:2230'],
        }
        cache = Cache(app, config=config)

        # use a wrong memcached connection
        try:
            cache.get(u"á_complex_operation")
        except Exception:
            pass


        # ensure that the error is not caused by our tracer
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "get")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.meta[CACHE_BACKEND], "memcached")
        eq_(span.meta[net.TARGET_HOST], 'localhost')
        eq_(span.meta[net.TARGET_PORT], '2230')
Esempio n. 12
0
    def test_simple_cache_set_many(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        cache.set_many({
            'first_complex_op': 10,
            'second_complex_op': 20,
        })
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "set_many")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 0)

        expected_meta = {
            "flask_cache.key": "['first_complex_op', 'second_complex_op']",
            "flask_cache.backend": "simple",
        }

        eq_(span.meta["flask_cache.backend"], "simple")
        ok_("first_complex_op" in span.meta["flask_cache.key"])
        ok_("second_complex_op" in span.meta["flask_cache.key"])
Esempio n. 13
0
    def test_simple_cache_delete_many(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        cache.delete_many("complex_operation", "another_complex_op")
        spans = writer.pop()
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "delete_many")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 0)

        expected_meta = {
            "flask_cache.key": "['complex_operation', 'another_complex_op']",
            "flask_cache.backend": "simple",
        }

        eq_(span.meta, expected_meta)
Esempio n. 14
0
    def test_long_run(self):
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # Test a big matrix of combinaisons
        # Ensure to have total_time >> BUFFER_DURATION to reduce edge effects
        for tps in [10, 23, 15, 31]:
            for (traces_per_s, total_time) in [(80, 23), (75, 66), (1000, 77)]:

                with patch_time() as fake_time:
                    # We do tons of operations in this test, do not let the time slowly shift
                    fake_time.set_delta(0)

                    tracer.sampler = ThroughputSampler(tps)

                    for _ in range(total_time):
                        for _ in range(traces_per_s):
                            s = tracer.trace("whatever")
                            s.finish()
                        fake_time.sleep(1)

                traces = writer.pop()
                # The current sampler implementation can introduce an error of up to
                # `tps * BUFFER_DURATION` traces at initialization (since the sampler starts empty)
                got = len(traces)
                expected = tps * total_time
                error_delta = tps * tracer.sampler.BUFFER_DURATION

                assert abs(got - expected) <= error_delta, \
                    "Wrong number of traces sampled, %s instead of %s (error_delta > %s)" % (got, expected, error_delta)
Esempio n. 15
0
    def test_simple_limit(self):
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        with patch_time() as fake_time:
            tps = 5
            tracer.sampler = ThroughputSampler(tps)

            for _ in range(10):
                s = tracer.trace("whatever")
                s.finish()
            traces = writer.pop()

            got = len(traces)
            expected = 10

            assert got == expected, \
                "Wrong number of traces sampled, %s instead of %s" % (got, expected)

            # Wait enough to reset
            fake_time.sleep(tracer.sampler.BUFFER_DURATION + 1)

            for _ in range(100):
                s = tracer.trace("whatever")
                s.finish()
            traces = writer.pop()

            got = len(traces)
            expected = tps * tracer.sampler.BUFFER_DURATION

            assert got == expected, \
                "Wrong number of traces sampled, %s instead of %s" % (got, expected)
Esempio n. 16
0
    def test_sample_rate_deviation(self):
        writer = DummyWriter()

        for sample_rate in [0.1, 0.25, 0.5, 1]:
            tracer = Tracer()
            tracer.writer = writer

            sample_rate = 0.5
            tracer.sampler = RateSampler(sample_rate)

            random.seed(1234)

            iterations = int(2e4)

            for i in range(iterations):
                span = tracer.trace(i)
                span.finish()

            samples = writer.pop()

            # We must have at least 1 sample, check that it has its sample rate properly assigned
            assert samples[0].get_metric(SAMPLE_RATE_METRIC_KEY) == 0.5

            # Less than 1% deviation when "enough" iterations (arbitrary, just check if it converges)
            deviation = abs(len(samples) -
                            (iterations * sample_rate)) / (iterations *
                                                           sample_rate)
            assert deviation < 0.01, "Deviation too high %f with sample_rate %f" % (
                deviation, sample_rate)
Esempio n. 17
0
def test_tracer_wrap_factory_nested():
    # it should use a wrap_factory if defined even in nested tracing
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    def wrap_executor(tracer, fn, args, kwargs, span_name=None, service=None, resource=None, span_type=None):
        with tracer.trace('wrap.overwrite') as span:
            span.set_tag('args', args)
            span.set_tag('kwargs', kwargs)
            return fn(*args, **kwargs)

    @tracer.wrap()
    def wrapped_function(param, kw_param=None):
        eq_(42, param)
        eq_(42, kw_param)

    # set the custom wrap factory after the wrapper has been called
    tracer.configure(wrap_executor=wrap_executor)

    # call the function expecting that the custom tracing wrapper is used
    with tracer.trace('wrap.parent', service='webserver'):
        wrapped_function(42, kw_param=42)

    eq_(writer.spans[0].name, 'wrap.parent')
    eq_(writer.spans[0].service, 'webserver')

    eq_(writer.spans[1].name, 'wrap.overwrite')
    eq_(writer.spans[1].service, 'webserver')
    eq_(writer.spans[1].get_tag('args'), '(42,)')
    eq_(writer.spans[1].get_tag('kwargs'), '{\'kw_param\': 42}')
Esempio n. 18
0
    def test_cache_add_without_arguments(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={"CACHE_TYPE": "simple"})

        # make a wrong call
        with assert_raises(TypeError) as ex:
            cache.add()

        # ensure that the error is not caused by our tracer
        ok_("add()" in ex.exception.args[0])
        ok_("argument" in ex.exception.args[0])
        spans = writer.pop()
        # an error trace must be sent
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "add")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.error, 1)
Esempio n. 19
0
    def test_redis_cache_tracing_with_a_wrong_connection(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        config = {
            "CACHE_TYPE": "redis",
            "CACHE_REDIS_PORT": 22230,
        }
        cache = Cache(app, config=config)

        # use a wrong redis connection
        with assert_raises(ConnectionError) as ex:
            cache.get(u"á_complex_operation")

        # ensure that the error is not caused by our tracer
        ok_("localhost:22230. Connection refused." in ex.exception.args[0])
        spans = writer.pop()
        # an error trace must be sent
        eq_(len(spans), 1)
        span = spans[0]
        eq_(span.service, self.SERVICE)
        eq_(span.resource, "get")
        eq_(span.name, "flask_cache.cmd")
        eq_(span.span_type, "cache")
        eq_(span.meta[CACHE_BACKEND], "redis")
        eq_(span.meta[net.TARGET_HOST], 'localhost')
        eq_(span.meta[net.TARGET_PORT], '22230')
        eq_(span.error, 1)
Esempio n. 20
0
    def test_cache_add_without_arguments(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        cache = Cache(app, config={'CACHE_TYPE': 'simple'})

        # make a wrong call
        with pytest.raises(TypeError) as ex:
            cache.add()

        # ensure that the error is not caused by our tracer
        assert 'add()' in ex.value.args[0]
        assert 'argument' in ex.value.args[0]
        spans = writer.pop()
        # an error trace must be sent
        assert len(spans) == 1
        span = spans[0]
        assert span.service == self.SERVICE
        assert span.resource == 'add'
        assert span.name == 'flask_cache.cmd'
        assert span.span_type == 'cache'
        assert span.error == 1
Esempio n. 21
0
def test_tracer_wrap_class():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    class Foo(object):
        @staticmethod
        @tracer.wrap()
        def s():
            return 1

        @classmethod
        @tracer.wrap()
        def c(cls):
            return 2

        @tracer.wrap()
        def i(cls):
            return 3

    f = Foo()
    eq_(f.s(), 1)
    eq_(f.c(), 2)
    eq_(f.i(), 3)

    spans = writer.pop()
    eq_(len(spans), 3)
    names = [s.name for s in spans]
    # FIXME[matt] include the class name here.
    eq_(sorted(names),
        sorted(["tests.test_tracer.%s" % n for n in ["s", "c", "i"]]))
Esempio n. 22
0
    def test_memcached_cache_tracing_with_a_wrong_connection(self):
        # initialize the dummy writer
        writer = DummyWriter()
        tracer = Tracer()
        tracer.writer = writer

        # create the TracedCache instance for a Flask app
        Cache = get_traced_cache(tracer, service=self.SERVICE)
        app = Flask(__name__)
        config = {
            'CACHE_TYPE': 'memcached',
            'CACHE_MEMCACHED_SERVERS': ['localhost:2230'],
        }
        cache = Cache(app, config=config)

        # use a wrong memcached connection
        try:
            cache.get(u'á_complex_operation')
        except Exception:
            pass

        # ensure that the error is not caused by our tracer
        spans = writer.pop()
        assert len(spans) == 1
        span = spans[0]
        assert span.service == self.SERVICE
        assert span.resource == 'get'
        assert span.name == 'flask_cache.cmd'
        assert span.span_type == 'cache'
        assert span.meta[CACHE_BACKEND] == 'memcached'
        assert span.meta[net.TARGET_HOST] == 'localhost'
        assert span.metrics[net.TARGET_PORT] == 2230
Esempio n. 23
0
def test_tracer_trace_across_fork():
    """
    When a trace is started in a parent process and a child process is spawned
        The trace should be continued in the child process
    """
    tracer = Tracer()
    tracer.writer = DummyWriter()

    def task(tracer, q):
        tracer.writer = DummyWriter()
        with tracer.trace("child"):
            pass
        spans = tracer.writer.pop()
        q.put(
            [dict(trace_id=s.trace_id, parent_id=s.parent_id) for s in spans])

    # Assert tracer in a new process correctly recreates the writer
    q = multiprocessing.Queue()
    with tracer.trace("parent") as parent:
        p = multiprocessing.Process(target=task, args=(tracer, q))
        p.start()
        p.join()

    children = q.get()
    assert len(children) == 1
    (child, ) = children
    assert parent.trace_id == child["trace_id"]
    assert child["parent_id"] == parent.span_id
Esempio n. 24
0
def test_tracer_pid():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer
    with tracer.trace("root") as root_span:
        with tracer.trace("child") as child_span:
            time.sleep(0.05)
    eq_(root_span.get_tag(system.PID), str(getpid())) # Root span should contain the pid of the current process
    eq_(child_span.get_tag(system.PID), None) # Child span should not contain a pid tag
Esempio n. 25
0
def test_tracer_pid():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer
    with tracer.trace("root") as root_span:
        with tracer.trace("child") as child_span:
            time.sleep(0.05)
    eq_(root_span.get_tag(system.PID), str(getpid())) # Root span should contain the pid of the current process
    eq_(child_span.get_tag(system.PID), None) # Child span should not contain a pid tag
Esempio n. 26
0
def test_tracer_wrap_default_name():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap()
    def f():
        pass
    f()

    eq_(writer.spans[0].name, 'tests.test_tracer.f')
Esempio n. 27
0
def test_manual_keep_then_drop():
    tracer = Tracer()
    tracer.writer = DummyWriter()

    # Test changing the value before finish.
    with tracer.trace("asdf") as root:
        with tracer.trace("child") as child:
            child.set_tag(MANUAL_KEEP_KEY)
        root.set_tag(MANUAL_DROP_KEY)
    spans = tracer.writer.pop()
    assert spans[0].metrics[SAMPLING_PRIORITY_KEY] is priority.USER_REJECT
Esempio n. 28
0
def test_tracer_wrap_default_name():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap()
    def f():
        pass
    f()

    eq_(writer.spans[0].name, 'tests.test_tracer.f')
Esempio n. 29
0
def test_tracer_wrap_exception():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap()
    def f():
        raise Exception('bim')

    assert_raises(Exception, f)

    eq_(len(writer.spans), 1)
    eq_(writer.spans[0].error, 1)
Esempio n. 30
0
 def setUp(self):
     tracer = Tracer()
     tracer.writer = DummyWriter()
     self.tracer = tracer
     # Backup the old conf
     self.backupTracer = settings.TRACER
     self.backupEnabled = settings.ENABLED
     # Disable tracing
     settings.ENABLED = False
     settings.TRACER = tracer
     # Restart the app
     app = apps.get_app_config('datadog_django')
     app.ready()
Esempio n. 31
0
def test_tracer_wrap_exception():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap()
    def f():
        raise Exception('bim')

    assert_raises(Exception, f)

    eq_(len(writer.spans), 1)
    eq_(writer.spans[0].error, 1)
Esempio n. 32
0
def test_tracer():
    # add some dummy tracing code.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer
    sleep = 0.05

    def _mix():
        with tracer.trace("cake.mix"):
            time.sleep(sleep)

    def _bake():
        with tracer.trace("cake.bake"):
            time.sleep(sleep)

    def _make_cake():
        with tracer.trace("cake.make") as span:
            span.service = "baker"
            span.resource = "cake"
            _mix()
            _bake()

    # let's run it and make sure all is well.
    assert not writer.spans
    _make_cake()
    spans = writer.pop()
    assert spans, "%s" % spans
    eq_(len(spans), 3)
    spans_by_name = {s.name:s for s in spans}
    eq_(len(spans_by_name), 3)

    make = spans_by_name["cake.make"]
    assert make.span_id
    assert make.parent_id is None
    assert make.trace_id

    for other in ["cake.mix", "cake.bake"]:
        s = spans_by_name[other]
        eq_(s.parent_id, make.span_id)
        eq_(s.trace_id, make.trace_id)
        eq_(s.service, make.service) # ensure it inherits the service
        eq_(s.resource, s.name)      # ensure when we don't set a resource, it's there.


    # do it again and make sure it has new trace ids
    _make_cake()
    spans = writer.pop()
    for s in spans:
        assert s.trace_id != make.trace_id
Esempio n. 33
0
def test_tracer():
    # add some dummy tracing code.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer
    sleep = 0.05

    def _mix():
        with tracer.trace("cake.mix"):
            time.sleep(sleep)

    def _bake():
        with tracer.trace("cake.bake"):
            time.sleep(sleep)

    def _make_cake():
        with tracer.trace("cake.make") as span:
            span.service = "baker"
            span.resource = "cake"
            _mix()
            _bake()

    # let's run it and make sure all is well.
    assert not writer.spans
    _make_cake()
    spans = writer.pop()
    assert spans, "%s" % spans
    eq_(len(spans), 3)
    spans_by_name = {s.name: s for s in spans}
    eq_(len(spans_by_name), 3)

    make = spans_by_name["cake.make"]
    assert make.span_id
    assert make.parent_id is None
    assert make.trace_id

    for other in ["cake.mix", "cake.bake"]:
        s = spans_by_name[other]
        eq_(s.parent_id, make.span_id)
        eq_(s.trace_id, make.trace_id)
        eq_(s.service, make.service)  # ensure it inherits the service
        eq_(s.resource,
            s.name)  # ensure when we don't set a resource, it's there.

    # do it again and make sure it has new trace ids
    _make_cake()
    spans = writer.pop()
    for s in spans:
        assert s.trace_id != make.trace_id
Esempio n. 34
0
def test_tracer_disabled_mem_leak():
    # ensure that if the tracer is disabled, we still remove things from the
    # span buffer upon finishing.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    tracer.enabled = False
    s1 = tracer.trace("foo")
    s1.finish()
    p1 = tracer.current_span()
    s2 = tracer.trace("bar")
    assert not s2._parent, s2._parent
    s2.finish()
    assert not p1, p1
Esempio n. 35
0
def test_get_report_hostname_default(get_hostname):
    get_hostname.return_value = "test-hostname"
    tracer = Tracer()
    tracer.writer = DummyWriter()

    with override_global_config(dict(report_hostname=False)):
        with tracer.trace("span"):
            with tracer.trace("child"):
                pass

    spans = tracer.writer.pop()
    root = spans[0]
    child = spans[1]
    assert root.get_tag(HOSTNAME_KEY) is None
    assert child.get_tag(HOSTNAME_KEY) is None
Esempio n. 36
0
def test_tracer_wrap_multiple_calls():
    # Make sure that we create a new span each time the function is called
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap()
    def f():
        pass
    f()
    f()

    spans = writer.pop()
    eq_(len(spans), 2)
    assert spans[0].span_id != spans[1].span_id
Esempio n. 37
0
def test_unserializable_span_with_finish():
    try:
        import numpy as np
    except ImportError:
        raise SkipTest("numpy not installed")

    # a weird case where manually calling finish with an unserializable
    # span was causing an loop of serialization.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    with tracer.trace("parent") as span:
        span.metrics['as'] = np.int64(1) # circumvent the data checks
        span.finish()
Esempio n. 38
0
def test_tracer_disabled():
    # add some dummy tracing code.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    tracer.enabled = True
    with tracer.trace("foo") as s:
        s.set_tag("a", "b")
    assert writer.pop()

    tracer.enabled = False
    with tracer.trace("foo") as s:
        s.set_tag("a", "b")
    assert not writer.pop()
Esempio n. 39
0
def test_tracer_wrap_multiple_calls():
    # Make sure that we create a new span each time the function is called
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap()
    def f():
        pass
    f()
    f()

    spans = writer.pop()
    eq_(len(spans), 2)
    assert spans[0].span_id != spans[1].span_id
Esempio n. 40
0
def test_tracer_disabled():
    # add some dummy tracing code.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    tracer.enabled = True
    with tracer.trace("foo") as s:
        s.set_tag("a", "b")
    assert writer.pop()

    tracer.enabled = False
    with tracer.trace("foo") as s:
        s.set_tag("a", "b")
    assert not writer.pop()
Esempio n. 41
0
def test_tracer_disabled_mem_leak():
    # ensure that if the tracer is disabled, we still remove things from the
    # span buffer upon finishing.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    tracer.enabled = False
    s1 = tracer.trace("foo")
    s1.finish()
    p1 = tracer.current_span()
    s2 = tracer.trace("bar")
    assert not s2._parent, s2._parent
    s2.finish()
    assert not p1, p1
Esempio n. 42
0
def test_unserializable_span_with_finish():
    try:
        import numpy as np
    except ImportError:
        raise SkipTest("numpy not installed")

    # a weird case where manually calling finish with an unserializable
    # span was causing an loop of serialization.
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    with tracer.trace("parent") as span:
        span.metrics['as'] = np.int64(1)  # circumvent the data checks
        span.finish()
Esempio n. 43
0
def test_manual_drop():
    tracer = Tracer()
    tracer.writer = DummyWriter()

    # On a root span
    with tracer.trace("asdf") as s:
        s.set_tag(MANUAL_DROP_KEY)
    spans = tracer.writer.pop()
    assert spans[0].metrics[SAMPLING_PRIORITY_KEY] is priority.USER_REJECT

    # On a child span
    with tracer.trace("asdf"):
        with tracer.trace("child") as s:
            s.set_tag(MANUAL_DROP_KEY)
    spans = tracer.writer.pop()
    assert spans[0].metrics[SAMPLING_PRIORITY_KEY] is priority.USER_REJECT
Esempio n. 44
0
def test_tracer_vars():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    # explicit vars
    s = tracer.trace("a", service="s", resource="r", span_type="t")
    eq_(s.service, "s")
    eq_(s.resource, "r")
    eq_(s.span_type, "t")
    s.finish()

    # defaults
    s = tracer.trace("a")
    eq_(s.service, None)
    eq_(s.resource, "a") # inherits
    eq_(s.span_type, None)
Esempio n. 45
0
def test_tracer_vars():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    # explicit vars
    s = tracer.trace("a", service="s", resource="r", span_type="t")
    eq_(s.service, "s")
    eq_(s.resource, "r")
    eq_(s.span_type, "t")
    s.finish()

    # defaults
    s = tracer.trace("a")
    eq_(s.service, None)
    eq_(s.resource, "a")  # inherits
    eq_(s.span_type, None)
Esempio n. 46
0
def test_tracer_global_tags():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    s1 = tracer.trace('brie')
    s1.finish()
    assert not s1.meta

    tracer.set_tags({'env': 'prod'})
    s2 = tracer.trace('camembert')
    s2.finish()
    assert s2.meta == {'env': 'prod'}

    tracer.set_tags({'env': 'staging', 'other': 'tag'})
    s3 = tracer.trace('gruyere')
    s3.finish()
    assert s3.meta == {'env': 'staging', 'other': 'tag'}
Esempio n. 47
0
def test_tracer_global_tags():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    s1 = tracer.trace('brie')
    s1.finish()
    assert not s1.get_tag('env')
    assert not s1.get_tag('other')

    tracer.set_tags({'env': 'prod'})
    s2 = tracer.trace('camembert')
    s2.finish()
    assert s2.get_tag('env') == 'prod'
    assert not s2.get_tag('other')

    tracer.set_tags({'env': 'staging', 'other': 'tag'})
    s3 = tracer.trace('gruyere')
    s3.finish()
    assert s3.get_tag('env') == 'staging'
    assert s3.get_tag('other') == 'tag'
Esempio n. 48
0
def test_tracer_wrap():
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap('decorated_function', service='s', resource='r',
            span_type='t')
    def f(tag_name, tag_value):
        # make sure we can still set tags
        span = tracer.current_span()
        span.set_tag(tag_name, tag_value)
    f('a', 'b')

    spans = writer.pop()
    eq_(len(spans), 1)
    s = spans[0]
    eq_(s.name, 'decorated_function')
    eq_(s.service, 's')
    eq_(s.resource, 'r')
    eq_(s.span_type, 't')
    eq_(s.to_dict()['meta']['a'], 'b')
Esempio n. 49
0
def test_tracer_wrap_span_nesting():
    # Make sure that nested spans have the correct parents
    writer = DummyWriter()
    tracer = Tracer()
    tracer.writer = writer

    @tracer.wrap('inner')
    def inner():
        pass
    @tracer.wrap('outer')
    def outer():
        with tracer.trace('mid'):
            inner()
    outer()

    spans = writer.pop()
    eq_(len(spans), 3)

    # sift through the list so we're not dependent on span ordering within the
    # writer
    for span in spans:
        if span.name == 'outer':
            outer_span = span
        elif span.name == 'mid':
            mid_span = span
        elif span.name == 'inner':
            inner_span = span
        else:
            assert False, 'unknown span found'  # should never get here

    assert outer_span
    assert mid_span
    assert inner_span

    eq_(outer_span.parent_id, None)
    eq_(mid_span.parent_id, outer_span.span_id)
    eq_(inner_span.parent_id, mid_span.span_id)
Esempio n. 50
0
def get_dummy_tracer():
    tracer = Tracer()
    tracer.writer = DummyWriter()
    return tracer