Skip to content

Commit 7692dee

Browse files
lrafeeihmstepanek
andauthored
Use single import point for protobuf in grpc (#647)
Co-authored-by: Hannah Stepanek <[email protected]>
1 parent 94d699a commit 7692dee

File tree

4 files changed

+73
-62
lines changed

4 files changed

+73
-62
lines changed

tests/framework_grpc/_test_common.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import grpc
16-
import threading
1715
import functools
16+
import threading
17+
1818
from newrelic.api.application import application_instance
1919

2020

2121
def create_request(streaming_request, count=1, timesout=False):
22-
from sample_application.sample_application_pb2 import Message
22+
from sample_application import Message
2323

2424
def _message_stream():
2525
for i in range(count):
26-
yield Message(text='Hello World', count=count, timesout=timesout)
26+
yield Message(text="Hello World", count=count, timesout=timesout)
2727

2828
if streaming_request:
2929
request = _message_stream()
3030
else:
31-
request = Message(text='Hello World', count=count, timesout=timesout)
31+
request = Message(text="Hello World", count=count, timesout=timesout)
3232

3333
return request
3434

tests/framework_grpc/conftest.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,56 @@
1313
# limitations under the License.
1414

1515
import gc
16+
1617
import grpc
1718
import pytest
18-
import random
19-
20-
from testing_support.fixtures import (code_coverage_fixture,
21-
collector_agent_registration_fixture, collector_available_fixture)
19+
from testing_support.fixtures import ( # noqa
20+
code_coverage_fixture,
21+
collector_agent_registration_fixture,
22+
collector_available_fixture,
23+
)
2224
from testing_support.mock_external_grpc_server import MockExternalgRPCServer
25+
2326
import newrelic.packages.six as six
2427

2528
_coverage_source = [
26-
'newrelic.hooks.framework_grpc',
29+
"newrelic.hooks.framework_grpc",
2730
]
2831

2932
code_coverage = code_coverage_fixture(source=_coverage_source)
3033

3134
_default_settings = {
32-
'transaction_tracer.explain_threshold': 0.0,
33-
'transaction_tracer.transaction_threshold': 0.0,
34-
'transaction_tracer.stack_trace_threshold': 0.0,
35-
'debug.log_data_collector_payloads': True,
36-
'debug.record_transaction_failure': True,
35+
"transaction_tracer.explain_threshold": 0.0,
36+
"transaction_tracer.transaction_threshold": 0.0,
37+
"transaction_tracer.stack_trace_threshold": 0.0,
38+
"debug.log_data_collector_payloads": True,
39+
"debug.record_transaction_failure": True,
3740
}
3841

3942
collector_agent_registration = collector_agent_registration_fixture(
40-
app_name='Python Agent Test (framework_grpc)',
41-
default_settings=_default_settings)
43+
app_name="Python Agent Test (framework_grpc)", default_settings=_default_settings
44+
)
4245

4346

44-
@pytest.fixture(scope='session')
47+
@pytest.fixture(scope="session")
4548
def grpc_app_server():
4649
with MockExternalgRPCServer() as server:
4750
yield server, server.port
4851

4952

50-
@pytest.fixture(scope='session')
53+
@pytest.fixture(scope="session")
5154
def mock_grpc_server(grpc_app_server):
52-
from sample_application.sample_application_pb2_grpc import (
53-
add_SampleApplicationServicer_to_server)
54-
from sample_application import SampleApplicationServicer
55+
from sample_application import (
56+
SampleApplicationServicer,
57+
add_SampleApplicationServicer_to_server,
58+
)
59+
5560
server, port = grpc_app_server
56-
add_SampleApplicationServicer_to_server(
57-
SampleApplicationServicer(), server)
61+
add_SampleApplicationServicer_to_server(SampleApplicationServicer(), server)
5862
return port
5963

6064

61-
@pytest.fixture(scope='function', autouse=True)
65+
@pytest.fixture(scope="function", autouse=True)
6266
def gc_garbage_empty():
6367
yield
6468

@@ -72,8 +76,8 @@ def gc_garbage_empty():
7276
pass
7377

7478
from grpc._channel import _Rendezvous
75-
rendezvous_stored = sum(1 for o in gc.get_objects()
76-
if hasattr(o, '__class__') and isinstance(o, _Rendezvous))
79+
80+
rendezvous_stored = sum(1 for o in gc.get_objects() if hasattr(o, "__class__") and isinstance(o, _Rendezvous))
7781

7882
assert rendezvous_stored == 0
7983

@@ -89,17 +93,14 @@ def stub(stub_and_channel):
8993
@pytest.fixture(scope="session")
9094
def stub_and_channel(mock_grpc_server):
9195
port = mock_grpc_server
92-
from sample_application.sample_application_pb2_grpc import (
93-
SampleApplicationStub)
94-
9596
stub, channel = create_stub_and_channel(port)
9697
with channel:
9798
yield stub, channel
9899

100+
99101
def create_stub_and_channel(port):
100-
from sample_application.sample_application_pb2_grpc import (
101-
SampleApplicationStub)
102+
from sample_application import SampleApplicationStub
102103

103-
channel = grpc.insecure_channel('localhost:%s' % port)
104+
channel = grpc.insecure_channel("localhost:%s" % port)
104105
stub = SampleApplicationStub(channel)
105106
return stub, channel

tests/framework_grpc/sample_application/__init__.py

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,84 +14,94 @@
1414

1515
import json
1616
import time
17-
from newrelic.api.transaction import current_transaction
17+
1818
import grpc
19+
import sample_application_pb2_grpc
1920

20-
from sample_application_pb2 import Message
21-
from sample_application_pb2_grpc import (
22-
SampleApplicationServicer as _SampleApplicationServicer)
21+
from newrelic.api.transaction import current_transaction
22+
23+
# This import format is to resolve a bug within protobuf 4
24+
# Issues for reference:
25+
# https://github.com/protocolbuffers/protobuf/issues/10075
26+
# https://github.com/protocolbuffers/protobuf/issues/10151
27+
# Within sample_application_pb2.py, the protobuf import can only
28+
# be done once before the DESCRIPTOR value is set to None
29+
# (in subsequent imports) instead of overriding/ignoring the imports.
30+
# This ensures that the imports happen once.
31+
Message = sample_application_pb2_grpc.sample__application__pb2.Message
32+
add_SampleApplicationServicer_to_server = sample_application_pb2_grpc.add_SampleApplicationServicer_to_server
33+
SampleApplicationStub = sample_application_pb2_grpc.SampleApplicationStub
2334

2435

2536
class Status(object):
2637
code = grpc.StatusCode.ABORTED
27-
details = 'abort_with_status'
38+
details = "abort_with_status"
2839
trailing_metadata = {}
2940

3041

31-
class SampleApplicationServicer(_SampleApplicationServicer):
32-
42+
class SampleApplicationServicer(sample_application_pb2_grpc.SampleApplicationServicer):
3343
def DoUnaryUnary(self, request, context):
34-
context.set_trailing_metadata([('content-type', 'text/plain')])
44+
context.set_trailing_metadata([("content-type", "text/plain")])
3545
if request.timesout:
3646
while context.is_active():
3747
time.sleep(0.1)
38-
return Message(text='unary_unary: %s' % request.text)
48+
return Message(text="unary_unary: %s" % request.text)
3949

4050
def DoUnaryStream(self, request, context):
41-
context.set_trailing_metadata([('content-type', 'text/plain')])
51+
context.set_trailing_metadata([("content-type", "text/plain")])
4252
if request.timesout:
4353
while context.is_active():
4454
time.sleep(0.1)
4555
for i in range(request.count):
46-
yield Message(text='unary_stream: %s' % request.text)
56+
yield Message(text="unary_stream: %s" % request.text)
4757

4858
def DoStreamUnary(self, request_iter, context):
49-
context.set_trailing_metadata([('content-type', 'text/plain')])
59+
context.set_trailing_metadata([("content-type", "text/plain")])
5060
for request in request_iter:
5161
if request.timesout:
5262
while context.is_active():
5363
time.sleep(0.1)
54-
return Message(text='stream_unary: %s' % request.text)
64+
return Message(text="stream_unary: %s" % request.text)
5565

5666
def DoStreamStream(self, request_iter, context):
57-
context.set_trailing_metadata([('content-type', 'text/plain')])
67+
context.set_trailing_metadata([("content-type", "text/plain")])
5868
for request in request_iter:
5969
if request.timesout:
6070
while context.is_active():
6171
time.sleep(0.1)
62-
yield Message(text='stream_stream: %s' % request.text)
72+
yield Message(text="stream_stream: %s" % request.text)
6373

6474
def DoUnaryUnaryRaises(self, request, context):
65-
raise AssertionError('unary_unary: %s' % request.text)
75+
raise AssertionError("unary_unary: %s" % request.text)
6676

6777
def DoUnaryStreamRaises(self, request, context):
68-
raise AssertionError('unary_stream: %s' % request.text)
78+
raise AssertionError("unary_stream: %s" % request.text)
6979

7080
def DoStreamUnaryRaises(self, request_iter, context):
7181
for request in request_iter:
72-
raise AssertionError('stream_unary: %s' % request.text)
82+
raise AssertionError("stream_unary: %s" % request.text)
7383

7484
def DoStreamStreamRaises(self, request_iter, context):
7585
for request in request_iter:
76-
raise AssertionError('stream_stream: %s' % request.text)
86+
raise AssertionError("stream_stream: %s" % request.text)
7787

7888
def NoTxnUnaryUnaryRaises(self, request, context):
7989
current_transaction().ignore_transaction = True
80-
raise AssertionError('unary_unary: %s' % request.text)
90+
raise AssertionError("unary_unary: %s" % request.text)
8191

8292
def NoTxnUnaryStreamRaises(self, request, context):
8393
current_transaction().ignore_transaction = True
84-
raise AssertionError('unary_stream: %s' % request.text)
94+
raise AssertionError("unary_stream: %s" % request.text)
8595

8696
def NoTxnStreamUnaryRaises(self, request_iter, context):
8797
current_transaction().ignore_transaction = True
8898
for request in request_iter:
89-
raise AssertionError('stream_unary: %s' % request.text)
99+
raise AssertionError("stream_unary: %s" % request.text)
90100

91101
def NoTxnStreamStreamRaises(self, request_iter, context):
92102
current_transaction().ignore_transaction = True
93103
for request in request_iter:
94-
raise AssertionError('stream_stream: %s' % request.text)
104+
raise AssertionError("stream_stream: %s" % request.text)
95105

96106
def NoTxnUnaryUnary(self, request, context):
97107
current_transaction().ignore_transaction = True
@@ -110,16 +120,16 @@ def NoTxnStreamStream(self, request_iter, context):
110120
return self.DoStreamStream(request_iter, context)
111121

112122
def DoUnaryUnaryAbort(self, request, context):
113-
context.abort(grpc.StatusCode.ABORTED, 'aborting')
123+
context.abort(grpc.StatusCode.ABORTED, "aborting")
114124

115125
def DoUnaryStreamAbort(self, request, context):
116-
context.abort(grpc.StatusCode.ABORTED, 'aborting')
126+
context.abort(grpc.StatusCode.ABORTED, "aborting")
117127

118128
def DoStreamUnaryAbort(self, request_iter, context):
119-
context.abort(grpc.StatusCode.ABORTED, 'aborting')
129+
context.abort(grpc.StatusCode.ABORTED, "aborting")
120130

121131
def DoStreamStreamAbort(self, request_iter, context):
122-
context.abort(grpc.StatusCode.ABORTED, 'aborting')
132+
context.abort(grpc.StatusCode.ABORTED, "aborting")
123133

124134
def DoUnaryUnaryAbortWithStatus(self, request, context):
125135
context.abort_with_status(Status)

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ envlist =
133133
python-framework_graphql-{py37,py38,py39,py310,pypy37}-graphql03,
134134
; temporarily disabling graphqlmaster tests
135135
python-framework_graphql-py37-graphql{0202,0203,0300,0301,0302},
136-
grpc-framework_grpc-{py27}-grpc0125,
136+
grpc-framework_grpc-py27-grpc0125,
137137
grpc-framework_grpc-{py37,py38,py39,py310}-grpclatest,
138138
python-framework_pyramid-{pypy,py27,py38}-Pyramid0104,
139139
python-framework_pyramid-{pypy,py27,pypy37,py37,py38,py39,py310}-Pyramid0110-cornice,
@@ -320,7 +320,7 @@ deps =
320320
framework_graphql-graphql0301: graphql-core<3.2
321321
framework_graphql-graphql0302: graphql-core<3.3
322322
framework_graphql-graphqlmaster: https://github.com/graphql-python/graphql-core/archive/main.zip
323-
framework_grpc-grpclatest: protobuf<4
323+
framework_grpc-grpclatest: protobuf
324324
framework_grpc-grpclatest: grpcio
325325
framework_grpc-grpclatest: grpcio-tools
326326
grpc0125: grpcio<1.26

0 commit comments

Comments
 (0)