1
- import os
2
-
3
1
import grpc
4
2
import pytest
5
3
6
4
from concurrent import futures
7
- from typing import List , Optional
5
+ from typing import List , Optional , Tuple
8
6
from unittest .mock import Mock
9
7
10
8
from sentry_sdk import start_span , start_transaction
19
17
)
20
18
21
19
22
- PORT = 50051
23
- PORT += os .getpid () % 100 # avoid port conflicts when running tests in parallel
24
-
25
-
26
- def _set_up (interceptors : Optional [List [grpc .ServerInterceptor ]] = None ):
20
+ # Set up in-memory channel instead of network-based
21
+ def _set_up (
22
+ interceptors : Optional [List [grpc .ServerInterceptor ]] = None ,
23
+ ) -> Tuple [grpc .Server , grpc .Channel ]:
24
+ """
25
+ Sets up a gRPC server and returns both the server and a channel connected to it.
26
+ This eliminates network dependencies and makes tests more reliable.
27
+ """
28
+ # Create server with thread pool
27
29
server = grpc .server (
28
30
futures .ThreadPoolExecutor (max_workers = 2 ),
29
31
interceptors = interceptors ,
30
32
)
31
33
32
- add_gRPCTestServiceServicer_to_server (TestService (), server )
33
- server .add_insecure_port ("[::]:{}" .format (PORT ))
34
+ # Add our test service to the server
35
+ servicer = TestService ()
36
+ add_gRPCTestServiceServicer_to_server (servicer , server )
37
+
38
+ # Use dynamic port allocation instead of hardcoded port
39
+ port = server .add_insecure_port ("[::]:0" ) # Let gRPC choose an available port
34
40
server .start ()
35
41
36
- return server
42
+ # Create channel connected to our server
43
+ channel = grpc .insecure_channel (f"localhost:{ port } " ) # noqa: E231
44
+
45
+ return server , channel
37
46
38
47
39
48
def _tear_down (server : grpc .Server ):
40
- server .stop (None )
49
+ server .stop (grace = None ) # Immediate shutdown
41
50
42
51
43
52
@pytest .mark .forked
44
53
def test_grpc_server_starts_transaction (sentry_init , capture_events_forksafe ):
45
54
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
46
55
events = capture_events_forksafe ()
47
56
48
- server = _set_up ()
57
+ server , channel = _set_up ()
49
58
50
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
51
- stub = gRPCTestServiceStub (channel )
52
- stub .TestServe (gRPCTestMessage (text = "test" ))
59
+ # Use the provided channel
60
+ stub = gRPCTestServiceStub (channel )
61
+ stub .TestServe (gRPCTestMessage (text = "test" ))
53
62
54
63
_tear_down (server = server )
55
64
@@ -76,11 +85,11 @@ def test_grpc_server_other_interceptors(sentry_init, capture_events_forksafe):
76
85
mock_interceptor = Mock ()
77
86
mock_interceptor .intercept_service .side_effect = mock_intercept
78
87
79
- server = _set_up (interceptors = [mock_interceptor ])
88
+ server , channel = _set_up (interceptors = [mock_interceptor ])
80
89
81
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
82
- stub = gRPCTestServiceStub (channel )
83
- stub .TestServe (gRPCTestMessage (text = "test" ))
90
+ # Use the provided channel
91
+ stub = gRPCTestServiceStub (channel )
92
+ stub .TestServe (gRPCTestMessage (text = "test" ))
84
93
85
94
_tear_down (server = server )
86
95
@@ -103,30 +112,30 @@ def test_grpc_server_continues_transaction(sentry_init, capture_events_forksafe)
103
112
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
104
113
events = capture_events_forksafe ()
105
114
106
- server = _set_up ()
115
+ server , channel = _set_up ()
107
116
108
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
109
- stub = gRPCTestServiceStub (channel )
117
+ # Use the provided channel
118
+ stub = gRPCTestServiceStub (channel )
110
119
111
- with start_transaction () as transaction :
112
- metadata = (
113
- (
114
- "baggage" ,
115
- "sentry-trace_id={trace_id},sentry-environment=test,"
116
- "sentry-transaction=test-transaction,sentry-sample_rate=1.0" .format (
117
- trace_id = transaction .trace_id
118
- ),
120
+ with start_transaction () as transaction :
121
+ metadata = (
122
+ (
123
+ "baggage" ,
124
+ "sentry-trace_id={trace_id},sentry-environment=test,"
125
+ "sentry-transaction=test-transaction,sentry-sample_rate=1.0" .format (
126
+ trace_id = transaction .trace_id
119
127
),
120
- (
121
- "sentry-trace" ,
122
- "{trace_id}-{parent_span_id}-{sampled}" . format (
123
- trace_id = transaction . trace_id ,
124
- parent_span_id = transaction .span_id ,
125
- sampled = 1 ,
126
- ) ,
128
+ ),
129
+ (
130
+ "sentry-trace" ,
131
+ "{ trace_id}-{parent_span_id}-{sampled}" . format (
132
+ trace_id = transaction .trace_id ,
133
+ parent_span_id = transaction . span_id ,
134
+ sampled = 1 ,
127
135
),
128
- )
129
- stub .TestServe (gRPCTestMessage (text = "test" ), metadata = metadata )
136
+ ),
137
+ )
138
+ stub .TestServe (gRPCTestMessage (text = "test" ), metadata = metadata )
130
139
131
140
_tear_down (server = server )
132
141
@@ -148,13 +157,13 @@ def test_grpc_client_starts_span(sentry_init, capture_events_forksafe):
148
157
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
149
158
events = capture_events_forksafe ()
150
159
151
- server = _set_up ()
160
+ server , channel = _set_up ()
152
161
153
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
154
- stub = gRPCTestServiceStub (channel )
162
+ # Use the provided channel
163
+ stub = gRPCTestServiceStub (channel )
155
164
156
- with start_transaction ():
157
- stub .TestServe (gRPCTestMessage (text = "test" ))
165
+ with start_transaction ():
166
+ stub .TestServe (gRPCTestMessage (text = "test" ))
158
167
159
168
_tear_down (server = server )
160
169
@@ -183,13 +192,13 @@ def test_grpc_client_unary_stream_starts_span(sentry_init, capture_events_forksa
183
192
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
184
193
events = capture_events_forksafe ()
185
194
186
- server = _set_up ()
195
+ server , channel = _set_up ()
187
196
188
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
189
- stub = gRPCTestServiceStub (channel )
197
+ # Use the provided channel
198
+ stub = gRPCTestServiceStub (channel )
190
199
191
- with start_transaction ():
192
- [el for el in stub .TestUnaryStream (gRPCTestMessage (text = "test" ))]
200
+ with start_transaction ():
201
+ [el for el in stub .TestUnaryStream (gRPCTestMessage (text = "test" ))]
193
202
194
203
_tear_down (server = server )
195
204
@@ -227,14 +236,14 @@ def test_grpc_client_other_interceptor(sentry_init, capture_events_forksafe):
227
236
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
228
237
events = capture_events_forksafe ()
229
238
230
- server = _set_up ()
239
+ server , channel = _set_up ()
231
240
232
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
233
- channel = grpc .intercept_channel (channel , MockClientInterceptor ())
234
- stub = gRPCTestServiceStub (channel )
241
+ # Intercept the channel
242
+ channel = grpc .intercept_channel (channel , MockClientInterceptor ())
243
+ stub = gRPCTestServiceStub (channel )
235
244
236
- with start_transaction ():
237
- stub .TestServe (gRPCTestMessage (text = "test" ))
245
+ with start_transaction ():
246
+ stub .TestServe (gRPCTestMessage (text = "test" ))
238
247
239
248
_tear_down (server = server )
240
249
@@ -267,13 +276,13 @@ def test_grpc_client_and_servers_interceptors_integration(
267
276
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
268
277
events = capture_events_forksafe ()
269
278
270
- server = _set_up ()
279
+ server , channel = _set_up ()
271
280
272
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
273
- stub = gRPCTestServiceStub (channel )
281
+ # Use the provided channel
282
+ stub = gRPCTestServiceStub (channel )
274
283
275
- with start_transaction ():
276
- stub .TestServe (gRPCTestMessage (text = "test" ))
284
+ with start_transaction ():
285
+ stub .TestServe (gRPCTestMessage (text = "test" ))
277
286
278
287
_tear_down (server = server )
279
288
@@ -290,13 +299,13 @@ def test_grpc_client_and_servers_interceptors_integration(
290
299
@pytest .mark .forked
291
300
def test_stream_stream (sentry_init ):
292
301
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
293
- server = _set_up ()
302
+ server , channel = _set_up ()
294
303
295
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
296
- stub = gRPCTestServiceStub (channel )
297
- response_iterator = stub .TestStreamStream (iter ((gRPCTestMessage (text = "test" ),)))
298
- for response in response_iterator :
299
- assert response .text == "test"
304
+ # Use the provided channel
305
+ stub = gRPCTestServiceStub (channel )
306
+ response_iterator = stub .TestStreamStream (iter ((gRPCTestMessage (text = "test" ),)))
307
+ for response in response_iterator :
308
+ assert response .text == "test"
300
309
301
310
_tear_down (server = server )
302
311
@@ -308,12 +317,12 @@ def test_stream_unary(sentry_init):
308
317
Tracing not supported for it yet.
309
318
"""
310
319
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
311
- server = _set_up ()
320
+ server , channel = _set_up ()
312
321
313
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
314
- stub = gRPCTestServiceStub (channel )
315
- response = stub .TestStreamUnary (iter ((gRPCTestMessage (text = "test" ),)))
316
- assert response .text == "test"
322
+ # Use the provided channel
323
+ stub = gRPCTestServiceStub (channel )
324
+ response = stub .TestStreamUnary (iter ((gRPCTestMessage (text = "test" ),)))
325
+ assert response .text == "test"
317
326
318
327
_tear_down (server = server )
319
328
@@ -323,13 +332,13 @@ def test_span_origin(sentry_init, capture_events_forksafe):
323
332
sentry_init (traces_sample_rate = 1.0 , integrations = [GRPCIntegration ()])
324
333
events = capture_events_forksafe ()
325
334
326
- server = _set_up ()
335
+ server , channel = _set_up ()
327
336
328
- with grpc . insecure_channel ( "localhost:{}" . format ( PORT )) as channel :
329
- stub = gRPCTestServiceStub (channel )
337
+ # Use the provided channel
338
+ stub = gRPCTestServiceStub (channel )
330
339
331
- with start_transaction (name = "custom_transaction" ):
332
- stub .TestServe (gRPCTestMessage (text = "test" ))
340
+ with start_transaction (name = "custom_transaction" ):
341
+ stub .TestServe (gRPCTestMessage (text = "test" ))
333
342
334
343
_tear_down (server = server )
335
344
0 commit comments