def test_run_hooks_and_send_presend_hook(self):
        ''' ensure send works when presend hook is defined '''
        def _presend_hook(fields):
            fields["thing i want"] = "put it there"
            del fields["thing i don't want"]
        m_presend_hook = Mock()
        m_presend_hook.side_effect = _presend_hook
        _beeline = beeline.Beeline(presend_hook=m_presend_hook)
        _beeline.tracer_impl = Mock()

        ev = Mock()
        ev.fields.return_value = {
            "thing i don't want": "get it out of here",
            "happy data": "so happy",
        }

        _beeline._run_hooks_and_send(ev)
        ev.send_presampled.assert_not_called()
        ev.send.assert_called_once_with()
        self.assertDictEqual(
            ev.fields(),
            {
                "thing i want": "put it there",
                "happy data": "so happy",
            },
        )
Example #2
0
    def test_generator_wrapper(self):
        ''' ensure that the trace wrapper decorates a generator function and starts a trace
            also ensure that child traces get the parent trace correctly set
        '''

        _beeline = beeline.Beeline()

        with patch('beeline.get_beeline') as m_gbl:
            m_gbl.return_value = _beeline
            _beeline.tracer_impl._run_hooks_and_send = Mock()

            @beeline.traced(name="return_integer_n")
            def return_integer(n):
                return n

            @beeline.traced(name="output_integers_to")
            def output_integers_to(n):
                for i in range(n):
                    yield return_integer(i)

            # should accept the function's arguments normally and yield the items from the
            # generator
            self.assertEqual(list(output_integers_to(3)), [0, 1, 2])

            self.assertTrue(_beeline.tracer_impl._run_hooks_and_send.called)

            spans = [x[0][0]
                     for x in _beeline.tracer_impl._run_hooks_and_send.call_args_list]

            # check the child spans now
            parent_span = spans[-1]
            child_spans = spans[:-1]

            for child_span in child_spans:
                self.assertEqual(child_span.parent_id, parent_span.id)
    def test_run_hooks_and_send_sampler(self):
        ''' ensure send works with a sampler hook defined '''
        def _sampler_drop_all(fields):
            return False, 0
        m_sampler_hook = Mock()
        m_sampler_hook.side_effect = _sampler_drop_all
        _beeline = beeline.Beeline(sampler_hook=m_sampler_hook)
        _beeline.tracer_impl = Mock()
        ev = Mock()

        _beeline._run_hooks_and_send(ev)
        m_sampler_hook.assert_called_once_with(ev.fields())
        ev.send_presampled.assert_not_called()
        ev.send.assert_not_called()

        def _sampler_drop_none(fields):
            return True, 100

        ev = Mock()
        m_sampler_hook.reset_mock()

        m_sampler_hook.side_effect = _sampler_drop_none

        _beeline._run_hooks_and_send(ev)
        m_sampler_hook.assert_called_once_with(ev.fields())
        self.assertEqual(ev.sample_rate, 100)
        ev.send_presampled.assert_called_once_with()
        ev.send.assert_not_called()
Example #4
0
    def test_synchronous_tracer_should_be_used_by_default(self):
        """Verify that the SynchronousTracer implementation is chosen when a
        Beeline object is initialised outside of an asyncio loop.

        """
        _beeline = beeline.Beeline()
        self.assertIsInstance(_beeline.tracer_impl,
                              beeline.trace.SynchronousTracer)
 def test_send_no_events(self):
     ''' ensure nothing crashes when we try to send with no events in the
     stack '''
     _beeline = beeline.Beeline()
     _beeline.tracer_impl = Mock()
     _beeline.tracer_impl.get_active_span.return_value = None
     _beeline.send_event()
     _beeline.tracer_impl.get_active_span.assert_called_once_with()
Example #6
0
    async def async_setup(self):
        self.finished_spans = []

        def add_span(span):
            self.finished_spans.append(span_data(span))

        self.beeline = beeline.Beeline()
        self.tracer = self.beeline.tracer_impl
        self.tracer._run_hooks_and_send = add_span
Example #7
0
    async def test_asyncio_tracer_should_be_used_in_async_code(self):
        """Verify that the AsyncioTracer implementation is chosen when a
        Beeline object is initialised while running inside an asyncio
        loop.

        """
        _beeline = beeline.Beeline()
        self.assertIsInstance(_beeline.tracer_impl,
                              beeline.aiotrace.AsyncioTracer)
 def test_send_event(self):
     ''' test correct behavior for send_event '''
     _beeline = beeline.Beeline()
     _beeline.tracer_impl = Mock()
     m_span = Mock()
     _beeline.tracer_impl.get_active_span.return_value = m_span
     _beeline.send_event()
     _beeline.tracer_impl.get_active_span.assert_called_once_with()
     _beeline.tracer_impl.finish_trace.assert_called_once_with(m_span)
    def test_run_hooks_and_send_no_hooks(self):
        ''' ensure send works when no hooks defined '''
        ev = Mock()
        _beeline = beeline.Beeline()
        _beeline.tracer_impl = Mock()
        _beeline._run_hooks_and_send(ev)

        # no hooks, not a traced event - call send
        ev.send.assert_called_once_with()
        ev.send_presampled.assert_not_called()
Example #10
0
    def test_trace_wrapper(self):
        ''' ensure that the trace wrapper decorates a function and starts a trace '''
        _beeline = beeline.Beeline()
        with patch('beeline.get_beeline') as m_gbl:
            m_gbl.return_value = _beeline
            _beeline.tracer_impl._run_hooks_and_send = Mock()

            @beeline.traced(name="my_sum")
            def my_sum(a, b):
                return a + b

            # this should accept the function's arguments normally and return the function's value
            # if there is one
            self.assertEqual(my_sum(1, 2), 3)
            # check that an event was sent, from which we can infer that the function was wrapped
            self.assertTrue(_beeline.tracer_impl._run_hooks_and_send.called)
Example #11
0
    def test_request_fn_injects_correct_context(self):
        ''' confirm that the injected trace context references the child span wrapping the request call '''
        from beeline.patch.requests import request  # pylint: disable=bad-option-value,import-outside-toplevel

        _beeline = beeline.Beeline(transmission_impl=Mock())
        # prevent spans from being sent/closed so we can get at the span generated by the request patch
        _beeline.tracer_impl.finish_span = Mock()

        with patch('beeline.get_beeline') as m_bl:
            m_bl.return_value = _beeline

            with _beeline.tracer("parent", trace_id="abc"):
                parent_span = _beeline.tracer_impl.get_active_span()

                # this is the class instance (Session object) that is passed to our request function by wrapt
                m_session = Mock()
                m_session.headers = {}

                # this is our request call that's being wrapped
                m_request = Mock()
                m_request.return_value = Mock(headers={
                    'content-type': 'application/json',
                    'content-length': 23
                },
                                              status_code=500)
                args = ['get']
                kwargs = {'url': 'http://example.com'}
                ret = request(m_request, m_session, args, kwargs)

                m_request.assert_called_once_with(*args, **kwargs)
                self.assertEqual(ret, m_request.return_value)

                self.assertEqual(len(_beeline.tracer_impl._trace.stack), 2)
                child_span = _beeline.tracer_impl.get_active_span()
                # we should have two distinct spans in this trace
                self.assertNotEqual(child_span.id, parent_span.id)
                self.assertEqual(child_span.parent_id, parent_span.id)

                trace_context = m_session.headers['X-Honeycomb-Trace']
                trace_id, parent_id, _ = beeline.trace.unmarshal_trace_context(
                    trace_context)
                # confirm the trace context parent is the child span, not the parent span
                self.assertEqual(child_span.trace_id, trace_id)
                self.assertEqual(child_span.id, parent_id)
                # should be the same trace
                self.assertEqual(parent_span.trace_id, trace_id)
Example #12
0
    def test_treaded_trace(self):
        _beeline = beeline.Beeline()

        with patch('beeline.get_beeline') as m_gbl:
            m_gbl.return_value = _beeline
            _beeline.tracer_impl._run_hooks_and_send = Mock()

            _beeline.tracer_impl.start_trace(trace_id="asdf")
            self.assertEqual(_beeline.tracer_impl._state.trace_id, "asdf")

            def thread_func():
                # confirm no trace state in new thread
                self.assertFalse(
                    hasattr(_beeline.tracer_impl._state, 'trace_id'))

            t = threading.Thread(target=thread_func)
            t.start()
            t.join()

            @beeline.traced_thread
            def traced_thread_func():
                self.assertEqual(_beeline.tracer_impl._state.trace_id, "asdf")

                with _beeline.tracer(name="foo") as span:
                    self.assertEqual(span.trace_id, "asdf")
                    self.assertEqual(span.parent_id,
                                     _beeline.tracer_impl._state.stack[0].id)

            t = threading.Thread(target=traced_thread_func)
            t.start()
            t.join()

            # test use of beeline client
            @_beeline.traced_thread
            def traced_thread_func_2():
                self.assertEqual(_beeline.tracer_impl._state.trace_id, "asdf")

                with _beeline.tracer(name="foo2") as span:
                    self.assertEqual(span.trace_id, "asdf")
                    self.assertEqual(span.parent_id,
                                     _beeline.tracer_impl._state.stack[0].id)

            t = threading.Thread(target=traced_thread_func_2)
            t.start()
            t.join()
Example #13
0
    def test_send_all(self):
        ''' ensure events are flushed, and that the root span is handled with
        finish_trace '''
        s1, s2, s3 = Mock(), Mock(), Mock()
        s1.is_root.return_value = False
        s2.is_root.return_value = False
        s3.is_root.return_value = True
        _beeline = beeline.Beeline()
        _beeline.tracer_impl = Mock()
        _beeline.tracer_impl.get_active_span.side_effect = [s1, s2, s3, None]

        _beeline.send_all()

        _beeline.tracer_impl.finish_span.assert_has_calls([
            call(s1),
            call(s2),
        ])
        _beeline.tracer_impl.finish_trace.assert_called_once_with(s3)
Example #14
0
    def test_treaded_trace(self):
        _beeline = beeline.Beeline()

        with patch('beeline.get_beeline') as m_gbl:
            m_gbl.return_value = _beeline
            _beeline.tracer_impl._run_hooks_and_send = Mock()

            _beeline.tracer_impl.start_trace(trace_id="asdf")
            self.assertEqual(_beeline.tracer_impl._trace.id, "asdf")

            def thread_func():
                # confirm no trace state in new thread
                self.assertIsNone(_beeline.tracer_impl._trace)

            self.raising_run_in_thread(target=thread_func)

            @beeline.traced_thread
            def traced_thread_func():
                self.assertEqual(_beeline.tracer_impl._trace.id, "asdf")

                with _beeline.tracer(name="foo") as span:
                    self.assertEqual(span.trace_id, "asdf")
                    self.assertEqual(span.parent_id,
                                     _beeline.tracer_impl._trace.stack[0].id)

            self.raising_run_in_thread(target=traced_thread_func)

            # test use of beeline client
            @_beeline.traced_thread
            def traced_thread_func_2():
                self.assertEqual(_beeline.tracer_impl._trace.id, "asdf")

                with _beeline.tracer(name="foo2") as span:
                    self.assertEqual(span.trace_id, "asdf")
                    self.assertEqual(span.parent_id,
                                     _beeline.tracer_impl._trace.stack[0].id)

            self.raising_run_in_thread(target=traced_thread_func_2)
Example #15
0
 def test_finish_span_none(self):
     ''' ensure finish_span does not crash if an empty span is passed to it '''
     _beeline = beeline.Beeline()
     # should not crash
     _beeline.tracer_impl.finish_span(None)