Exemple #1
0
def test_outbound_payload_outside_transaction(mock_grpc_server, method_type,
                                              method_name, stub):
    request_type, response_type = method_type.split('_', 1)
    streaming_request = request_type == 'stream'
    streaming_response = response_type == 'stream'
    stub_method = 'DtNoTxn' + method_type.title().replace('_', '')

    request = create_request(streaming_request)

    method_callable = getattr(stub, stub_method)
    method = getattr(method_callable, method_name)

    reply = method(request)

    if isinstance(reply, tuple):
        reply = reply[0]

    try:
        # If the reply was canceled or the server code raises an exception,
        # this will raise an exception which will be recorded by the agent
        if streaming_response:
            reply = list(reply)
        else:
            reply = [reply.result()]
    except (AttributeError, TypeError):
        reply = [reply]

    # Verify there were no DT headers sent
    metadata = json.loads(reply[0].text)

    assert 'newrelic' not in metadata
    assert 'traceparent' not in metadata
    assert 'tracestate' not in metadata
Exemple #2
0
def test_simple(method_name, streaming_request, mock_grpc_server, stub):
    port = mock_grpc_server
    request = create_request(streaming_request)
    _transaction_name = \
        "sample_application:SampleApplicationServicer.{}".format(method_name)
    method = getattr(stub, method_name)

    @validate_transaction_metrics(_transaction_name)
    @override_application_settings({'attributes.include': ['request.*']})
    @validate_transaction_event_attributes(required_params={
        'agent': [
            'request.uri', 'request.headers.userAgent', 'response.status',
            'response.headers.contentType'
        ],
        'user': [],
        'intrinsic': ['port'],
    },
                                           exact_attrs={
                                               'agent': {},
                                               'user': {},
                                               'intrinsic': {
                                                   'port': port
                                               }
                                           })
    @wait_for_transaction_completion
    def _doit():
        response = method(request)

        try:
            list(response)
        except Exception:
            pass

    _doit()
Exemple #3
0
def test_newrelic_disabled_no_transaction(mock_grpc_server, stub):
    port = mock_grpc_server
    request = create_request(False)

    method = getattr(stub, 'DoUnaryUnary')

    @override_generic_settings(global_settings(), {'enabled': False})
    @function_not_called('newrelic.core.stats_engine',
                         'StatsEngine.record_transaction')
    @wait_for_transaction_completion
    def _doit():
        method(request)

    _doit()
Exemple #4
0
def test_raises_response_status(method_name, streaming_request,
                                mock_grpc_server, stub):
    port = mock_grpc_server
    request = create_request(streaming_request)

    method_name = method_name + 'Raises'

    _transaction_name = \
        "sample_application:SampleApplicationServicer.{}".format(method_name)
    method = getattr(stub, method_name)

    status_code = str(grpc.StatusCode.UNKNOWN.value[0])

    @validate_code_level_metrics(
        "sample_application.SampleApplicationServicer", method_name)
    @validate_transaction_errors(errors=[
        select_python_version(py2='exceptions:AssertionError',
                              py3='builtins:AssertionError')
    ])
    @validate_transaction_metrics(_transaction_name)
    @override_application_settings({'attributes.include': ['request.*']})
    @validate_transaction_event_attributes(required_params={
        'agent':
        ['request.uri', 'request.headers.userAgent', 'response.status'],
        'user': [],
        'intrinsic': ['port'],
    },
                                           exact_attrs={
                                               'agent': {
                                                   'response.status':
                                                   status_code
                                               },
                                               'user': {},
                                               'intrinsic': {
                                                   'port': port
                                               }
                                           })
    @wait_for_transaction_completion
    def _doit():
        try:
            response = method(request)
            list(response)
        except Exception:
            pass

    _doit()
Exemple #5
0
def test_abort(method_name, streaming_request, mock_grpc_server, stub):
    port = mock_grpc_server
    request = create_request(streaming_request)
    method = getattr(stub, method_name + 'Abort')

    @validate_transaction_errors(errors=[
        select_python_version(py2='exceptions:Exception',
                              py3='builtins:Exception')
    ])
    @wait_for_transaction_completion
    def _doit():
        with pytest.raises(grpc.RpcError) as error:
            response = method(request)
            list(response)

        assert error.value.details() == 'aborting'
        assert error.value.code() == grpc.StatusCode.ABORTED

    _doit()
Exemple #6
0
def test_inbound_distributed_trace(mock_grpc_server, method_name,
                                   streaming_request, stub):
    request = create_request(streaming_request)

    transaction = Transaction(application_instance())
    dt_headers = ExternalTrace.generate_request_headers(transaction)

    @validate_transaction_metrics(
        'sample_application:SampleApplicationServicer.' + method_name,
        rollup_metrics=(('Supportability/TraceContext/Accept/Success', 1), ),
    )
    @wait_for_transaction_completion
    def _test():
        method = getattr(stub, method_name)
        response = method(request, metadata=dt_headers)

        try:
            list(response)
        except Exception:
            pass

    _test()
Exemple #7
0
def test_no_exception_client_close(mock_grpc_server):
    port = mock_grpc_server
    # We can't use the stub_and_channel fixture here as closing
    # that channel will cause any subsequent tests to fail.
    # Instead we create a brand new channel to close.
    stub, channel = create_stub_and_channel(port)

    with channel:
        request = create_request(False, timesout=True)

        method = getattr(stub, 'DoUnaryUnary')

        @validate_transaction_errors(errors=[])
        @wait_for_transaction_completion
        def _doit():
            future_response = method.future(request)
            channel.close()
            with pytest.raises(grpc.RpcError) as error:
                future_response.result()

            assert error.value.code() == grpc.StatusCode.CANCELLED

        _doit()
Exemple #8
0
def test_abort_with_status(method_name, streaming_request, mock_grpc_server,
                           stub):
    method_name += 'AbortWithStatus'
    port = mock_grpc_server
    request = create_request(streaming_request)
    method = getattr(stub, method_name)

    @validate_code_level_metrics(
        "sample_application.SampleApplicationServicer", method_name)
    @validate_transaction_errors(errors=[
        select_python_version(py2='exceptions:Exception',
                              py3='builtins:Exception')
    ])
    @wait_for_transaction_completion
    def _doit():
        with pytest.raises(grpc.RpcError) as error:
            response = method(request)
            list(response)

        assert error.value.details() == 'abort_with_status'
        assert error.value.code() == grpc.StatusCode.ABORTED

    _doit()
Exemple #9
0
def test_outbound_distributed_trace(mock_grpc_server, method_type, method_name,
                                    dt_enabled, dt_error, stub):
    request_type, response_type = method_type.split('_', 1)
    streaming_request = request_type == 'stream'
    streaming_response = response_type == 'stream'
    stub_method = 'DtNoTxn' + method_type.title().replace('_', '')

    request = create_request(streaming_request)

    method_callable = getattr(stub, stub_method)
    method = getattr(method_callable, method_name)

    exact_intrinsics = {
        'category': 'http',
        'span.kind': 'client',
    }

    txn_name = 'test_outbound_DT[{0}-{1}-{2}-{3}]'.format(
        method_type, method_name, dt_enabled, dt_error)
    settings = {'distributed_tracing.enabled': dt_enabled}
    span_count = 1 if dt_enabled else 0
    if dt_error:
        settings['trusted_account_key'] = None

    @override_application_settings(settings)
    @validate_span_events(count=span_count, exact_intrinsics=exact_intrinsics)
    @wait_for_transaction_completion
    @background_task(name=txn_name)
    def _test():
        # Always mark sampled as True. current_transaction() is guaranteed to
        # be non-None here as test fixtures ensure activation prior to testing.
        current_transaction()._sampled = True

        reply = method(request)

        if isinstance(reply, tuple):
            reply = reply[0]

        try:
            # If the reply was canceled or the server code raises an exception,
            # this will raise an exception which will be recorded by the agent
            if streaming_response:
                reply = list(reply)
            else:
                reply = [reply.result()]
        except (AttributeError, TypeError):
            reply = [reply]

        metadata = json.loads(reply[0].text)

        if not dt_enabled or dt_error:
            assert 'newrelic' not in metadata
            assert 'traceparent' not in metadata
            assert 'tracestate' not in metadata
        else:
            decoded = DistributedTracePayload.decode(metadata['newrelic'])

            # The external span should be the parent
            exact_intrinsics['guid'] = decoded['d']['id']

            # Check that tracestate / traceparent payload matches newrelic
            # payload
            w3c_data = W3CTraceParent.decode(metadata['traceparent'])
            nr_tracestate = list(
                W3CTraceState.decode(metadata['tracestate']).values())[0]
            nr_tracestate = NrTraceState.decode(nr_tracestate, None)
            w3c_data.update(nr_tracestate)

            # Remove all trust keys
            decoded['d'].pop('tk', None)
            w3c_data.pop('tk')

            assert decoded['d'] == w3c_data

    _test()