def _test():
        with BackgroundTask(application(), name='T1') as txn:
            txn._priority = first_priority
            try:
                raise ValueError('OOPS')
            except ValueError:
                txn.notice_error()

        with BackgroundTask(application(), name='T2') as txn:
            txn._priority = second_priority
            try:
                raise ValueError('OOPS')
            except ValueError:
                txn.notice_error()

        # Stats engine
        stats_engine = core_application_stats_engine()

        error_events = list(stats_engine.error_events)
        assert len(error_events) == 1

        # highest priority should win
        assert stats_engine.error_events.pq[0][0] == 1

        if first_transaction_saved:
            assert error_events[0][0]['transactionName'].endswith('/T1')
        else:
            assert error_events[0][0]['transactionName'].endswith('/T2')
Exemplo n.º 2
0
def test_nested_context_managers():
    app = application_instance()
    outer = BackgroundTask(app, 'outer')
    inner = BackgroundTask(app, 'inner')
    with outer:
        with inner:
            assert not inner.enabled
def test_dead_transaction_ends(circular):
    if circular and six.PY2:
        pytest.skip("Circular references in py2 result in a memory leak. "
                    "There is no way to remove transactions from the weakref "
                    "cache in this case.")

    transaction = BackgroundTask(application_instance(),
                                 "test_dead_transaction_ends")
    if circular:
        transaction._self = transaction

    transaction.__enter__()
    del transaction
    gc.collect()
Exemplo n.º 4
0
def test_sentinel_exited_complete_root_exception():
    """
    This test forces a transaction to exit while it still has an active trace
    this causes an exception to be raised in TraceCache complete_root(). It
    verifies that the sentinel.exited property is set to true if an exception
    is raised in complete_root()
    """
    expected_error = "not the current trace"

    try:
        txn = None
        sentinel = None
        txn = BackgroundTask(application_instance(), "Parent")
        txn.__enter__()
        sentinel = txn.root_span
        trace = FunctionTrace("trace")
        trace.__enter__()
        txn.__exit__(None, None, None)
        assert False, "Did not raise exception"
    except RuntimeError as e:
        assert str(e) == expected_error
    finally:
        assert sentinel.exited
        # Make sure to exit properly so cleanup is performed
        trace.__exit__(None, None, None)
        txn.__exit__(None, None, None)
def test_transaction_end_on_different_task():
    import asyncio

    txn = BackgroundTask(application(), name="Parent")

    async def parent():
        txn.__enter__()
        child_start = asyncio.Event()
        parent_end = asyncio.Event()
        child_task = asyncio.ensure_future(child(child_start, parent_end))
        await child_start.wait()
        parent_end.set()
        return child_task

    async def child(child_start, parent_end):
        child_start.set()
        await parent_end.wait()

        # Calling asyncio.sleep(0) allows the scheduled done callbacks to run
        # done callbacks are scheduled through call_soon
        await asyncio.sleep(0)
        txn.__exit__(None, None, None)

    async def test():
        task = await asyncio.ensure_future(parent())
        await task

    loop = asyncio.get_event_loop()
    loop.run_until_complete(test())
Exemplo n.º 6
0
def test_transport_get_connection():
    app = application()
    with BackgroundTask(app, 'transport_perform_request') as transaction:
        transport = Transport([HOST])
        transport.get_connection()

    expected = (ES_SETTINGS['host'], ES_SETTINGS['port'], None)
    assert transaction._nr_datastore_instance_info == expected
Exemplo n.º 7
0
def test_transport_perform_request_requests():
    app = application()
    with BackgroundTask(app, 'perform_request_requests') as transaction:
        transport = Transport([HOST], connection_class=RequestsHttpConnection)
        transport.perform_request('POST', METHOD, params=PARAMS, body=DATA)

    expected = (ES_SETTINGS['host'], ES_SETTINGS['port'], None)
    assert transaction._nr_datastore_instance_info == expected
async def trace_in_cache_txn_active(asyncio, bg):
    event = asyncio.Event()

    with BackgroundTask(application(), 'fg'):
        with FunctionTrace('fg') as _:
            task = asyncio.ensure_future(bg(event))
        await event.wait()

    return task
async def sentinel_in_cache_txn_exited(asyncio, bg):
    event = asyncio.Event()

    with BackgroundTask(application(), 'fg') as txn:
        _ = txn.root_span
        task = asyncio.ensure_future(bg(event))

    await event.wait()
    return task
Exemplo n.º 10
0
    def _make_test_transaction():
        application = application_instance()

        if not web_transaction:
            return BackgroundTask(application, transaction_name)

        environ = {'REQUEST_URI': '/trace_ends_after_txn'}
        tn = WSGIWebTransaction(application, environ)
        tn.set_transaction_name(transaction_name)
        return tn
    def _test():
        # Stats engine
        stats_engine = core_application_stats_engine()

        with BackgroundTask(application(), name='T1') as txn:
            txn._priority = first_priority

        with BackgroundTask(application(), name='T2') as txn:
            txn._priority = second_priority

        transaction_events = list(stats_engine.transaction_events)
        assert len(transaction_events) == 1

        # highest priority should win
        assert stats_engine.transaction_events.pq[0][0] == 1

        if first_transaction_saved:
            assert transaction_events[0][0]['name'].endswith('/T1')
        else:
            assert transaction_events[0][0]['name'].endswith('/T2')
Exemplo n.º 12
0
    def _make_test_transaction():
        application = application_instance()
        request = TestAsgiRequest()

        if not web_transaction:
            return BackgroundTask(application, transaction_name)

        tn = ASGIWebTransaction(application, request.scope, request.send,
                                request.receive)
        tn.set_transaction_name(transaction_name)
        return tn
    def _test():
        with BackgroundTask(application(), name='T1') as txn:
            txn._priority = first_priority
            txn.record_custom_event('foobar', {'foo': 'bar'})

        with BackgroundTask(application(), name='T2') as txn:
            txn._priority = second_priority
            txn.record_custom_event('barbaz', {'foo': 'bar'})

        # Stats engine
        stats_engine = core_application_stats_engine()

        custom_events = list(stats_engine.custom_events)
        assert len(custom_events) == 1

        # highest priority should win
        assert stats_engine.custom_events.pq[0][0] == 1

        if first_transaction_saved:
            assert custom_events[0][0]['type'] == 'foobar'
        else:
            assert custom_events[0][0]['type'] == 'barbaz'
Exemplo n.º 14
0
def wrapper_GearmanWorker_on_job_execute(wrapped, instance, args, kwargs):
    def _bind_params(current_job, *args, **kwargs):
        return current_job

    # The background task is always created against the default
    # application specified by the agent configuration. The background
    # task is named after the name the task function was registered as,
    # and prefixed by the special 'Gearman' group.

    application = default_application()
    current_job = _bind_params(*args, **kwargs)

    with BackgroundTask(application, current_job.task, 'Gearman'):
        return wrapped(*args, **kwargs)
Exemplo n.º 15
0
def test_transport_perform_request_urllib3():
    app = application()
    with BackgroundTask(app, 'perform_request_urllib3') as transaction:
        transport = Transport([HOST], connection_class=Urllib3HttpConnection)
        if VERSION >= (7, 16, 0):
            transport.perform_request('POST',
                                      METHOD,
                                      headers=HEADERS,
                                      params=PARAMS,
                                      body=DATA)
        else:
            transport.perform_request('POST', METHOD, params=PARAMS, body=DATA)
    expected = (ES_SETTINGS['host'], ES_SETTINGS['port'], None)
    assert transaction._nr_datastore_instance_info == expected
Exemplo n.º 16
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction()

        if callable(name):
            # Start Hotfix v2.2.1.
            #if instance and inspect.ismethod(wrapped):
            #    _name = name(instance, *args, **kwargs)
            #else:
            #    _name = name(*args, **kwargs)

            if instance is not None:
                _name = name(instance, *args, **kwargs)
            else:
                _name = name(*args, **kwargs)
            # End Hotfix v2.2.1.

        elif name is None:
            _name = callable_name(wrapped)

        else:
            _name = name

        # Helper for obtaining the appropriate application object. If
        # has an activate() method assume it is a valid application
        # object. Don't check by type so se can easily mock it for
        # testing if need be.

        def _application():
            if hasattr(application, 'activate'):
                return application
            return application_instance(application)

        # Check to see if we are being called within the context of an
        # existing transaction. If we are, then we will record the call
        # as a function trace node instead. This situation can occur
        # when a function wrapped with Celery task decorator is called
        # explicitly in the context of an existing transaction.

        if transaction:
            with FunctionTrace(transaction, callable_name(wrapped)):
                return wrapped(*args, **kwargs)

        # Otherwise treat it as top level background task.

        with BackgroundTask(_application(), _name, 'Celery'):
            return wrapped(*args, **kwargs)
Exemplo n.º 17
0
def test_sentinel_exited_complete_root_exception():
    """
    This test forces a transaction to exit while it still has an active trace
    this causes an exception to be raised in TraceCache complete_root(). It
    verifies that the sentinel.exited property is set to true if an exception
    is raised in complete_root(), and that the exception is caught.
    """

    txn = None
    sentinel = None
    txn = BackgroundTask(application_instance(), "Parent")
    txn.__enter__()
    sentinel = txn.root_span
    trace = FunctionTrace("trace")
    trace.__enter__()
    txn.__exit__(None, None, None)
    assert sentinel.exited
    # Make sure to exit properly so cleanup is performed
    trace.__exit__(None, None, None)
    txn.__exit__(None, None, None)
def _nr_wrapper_BaseCommand_run_from_argv_(wrapped, instance, args, kwargs):
    def _args(argv, *args, **kwargs):
        return argv

    _argv = _args(*args, **kwargs)

    subcommand = _argv[1]

    commands = django_settings.instrumentation.scripts.django_admin
    startup_timeout = \
            django_settings.instrumentation.background_task.startup_timeout

    if subcommand not in commands:
        return wrapped(*args, **kwargs)

    application = register_application(timeout=startup_timeout)

    with BackgroundTask(application, subcommand, 'Django'):
        return wrapped(*args, **kwargs)
def test_transaction_freeze_path_segments(testname, transaction_segment_terms,
        tests):

    application = current_application()

    # We can't check all possibilites by doing things via the transaction
    # as it not possible to set up a metric path of only one segment.

    with segment_rules(application.name, transaction_segment_terms):
        for test in tests:
            segments = test['input'].split()
            if len(segments) < 2:
                continue

            ttype = segments[0]
            group = '/'.join(segments[1:2])
            name = '/'.join(segments[2:])

            with BackgroundTask(application, name, group) as transaction:
                transaction.background_task = (ttype == 'OtherTransaction')

            assert transaction.path == test['expected']
Exemplo n.º 20
0
    def wrapper(wrapped, instance, args, kwargs):
        transaction = current_transaction(active_only=False)

        if callable(name):
            # Start Hotfix v2.2.1.
            # if instance and inspect.ismethod(wrapped):
            #     _name = name(instance, *args, **kwargs)
            # else:
            #     _name = name(*args, **kwargs)

            if instance is not None:
                _name = name(instance, *args, **kwargs)
            else:
                _name = name(*args, **kwargs)
            # End Hotfix v2.2.1.

        elif name is None:
            _name = callable_name(wrapped)

        else:
            _name = name

        # Helper for obtaining the appropriate application object. If
        # has an activate() method assume it is a valid application
        # object. Don't check by type so se can easily mock it for
        # testing if need be.

        def _application():
            if hasattr(application, 'activate'):
                return application
            return application_instance(application)

        # A Celery Task can be called either outside of a transaction, or
        # within the context of an existing transaction. There are 3
        # possibilities we need to handle:
        #
        #   1. In an inactive transaction
        #
        #      If the end_of_transaction() or ignore_transaction() API calls
        #      have been invoked, this task may be called in the context
        #      of an inactive transaction. In this case, don't wrap the task
        #      in any way. Just run the original function.
        #
        #   2. In an active transaction
        #
        #      Run the original function inside a FunctionTrace.
        #
        #   3. Outside of a transaction
        #
        #      This is the typical case for a celery Task. Since it's not
        #      running inside of an existing transaction, we want to create
        #      a new background transaction for it.

        if transaction and (transaction.ignore_transaction
                            or transaction.stopped):
            return wrapped(*args, **kwargs)

        elif transaction:
            with FunctionTrace(callable_name(wrapped)):
                return wrapped(*args, **kwargs)

        else:
            with BackgroundTask(_application(), _name, 'Celery'):
                return wrapped(*args, **kwargs)
 async def bg(event):
     with BackgroundTask(application(), 'bg'):
         event.set()