1+ import asyncio
12from signal import SIGTERM
23
34import pytest
@@ -20,8 +21,7 @@ async def test_graceful_shutdown_headers(service_daemon_instance, grpc_client, s
2021 ]
2122
2223 for headers_enabled , headers in params :
23- dynamic_config .set_values ({'GRACEFUL_SHUTDOWN_HEADERS' : {'enabled' : headers_enabled , 'headers' : headers }})
24- await service_client .update_server_state ()
24+ await update_graceful_shutdown_headers (service_client , dynamic_config , headers_enabled , headers )
2525
2626 request = greeter_protos .GreetingRequest (name = 'Python' )
2727 call = grpc_client .SayHello (request )
@@ -33,8 +33,7 @@ async def test_graceful_shutdown_headers(service_daemon_instance, grpc_client, s
3333 service_daemon_instance .process .send_signal (SIGTERM )
3434
3535 for headers_enabled , headers in params :
36- dynamic_config .set_values ({'GRACEFUL_SHUTDOWN_HEADERS' : {'enabled' : headers_enabled , 'headers' : headers }})
37- await service_client .update_server_state ()
36+ await update_graceful_shutdown_headers (service_client , dynamic_config , headers_enabled , headers )
3837
3938 request = greeter_protos .GreetingRequest (name = 'Python' )
4039 call = grpc_client .SayHello (request )
@@ -52,6 +51,83 @@ async def test_graceful_shutdown_headers(service_daemon_instance, grpc_client, s
5251 service_daemon_instance .process .wait ()
5352
5453
54+ @pytest .mark .uservice_oneshot
55+ async def test_graceful_shutdown_headers_streams (service_daemon_instance , grpc_client , service_client , dynamic_config ):
56+ headers = {'x-envoy-immediate-health-check-fail' : ['true' ]}
57+ await update_graceful_shutdown_headers (service_client , dynamic_config , True , headers )
58+
59+ start = f'Python{ MD_ONE_REQ } { MD_TWO_REQ } '
60+ end = f'{ MD_TWO_RES } { MD_ONE_RES } '
61+
62+ service_daemon_instance .process .send_signal (SIGTERM )
63+
64+ call = grpc_client .SayHelloStreams (
65+ _prepare_requests (['Python' , '!' , '!' , '!' ], 0.1 ),
66+ wait_for_ready = True ,
67+ )
68+ async for response in call :
69+ assert response .greeting == f'Hello, { start } { end } '
70+ start += f'!{ MD_ONE_REQ } { MD_TWO_REQ } '
71+
72+ check_present (await call .initial_metadata (), headers )
73+ check_not_present (await call .trailing_metadata (), headers )
74+
75+ # After a couple more seconds, the service will start shutting down.
76+ service_daemon_instance .process .wait ()
77+
78+
79+ @pytest .mark .uservice_oneshot
80+ async def test_late_graceful_shutdown_headers_streams (
81+ service_daemon_instance , grpc_client , service_client , dynamic_config
82+ ):
83+ headers = {'x-envoy-immediate-health-check-fail' : ['true' ]}
84+ await update_graceful_shutdown_headers (service_client , dynamic_config , True , headers )
85+
86+ start = f'Python{ MD_ONE_REQ } { MD_TWO_REQ } '
87+ end = f'{ MD_TWO_RES } { MD_ONE_RES } '
88+
89+ call = grpc_client .SayHelloStreams (
90+ _prepare_late_requests (service_daemon_instance , ['Python' , '!' , '!' ], 0.2 ),
91+ wait_for_ready = True ,
92+ )
93+ async for response in call :
94+ assert response .greeting == f'Hello, { start } { end } '
95+ start += f'!{ MD_ONE_REQ } { MD_TWO_REQ } '
96+
97+ check_not_present (await call .initial_metadata (), headers )
98+ check_present (await call .trailing_metadata (), headers )
99+
100+ # After a couple more seconds, the service will start shutting down.
101+ service_daemon_instance .process .wait ()
102+
103+
104+ async def _prepare_requests (names , sleep = 1 ):
105+ reqs = []
106+ for name in names :
107+ reqs .append (greeter_protos .GreetingRequest (name = name ))
108+ for req in reqs :
109+ await asyncio .sleep (sleep )
110+ yield req
111+
112+
113+ async def _prepare_late_requests (service_daemon_instance , names , sleep = 1 ):
114+ reqs = []
115+ for name in names :
116+ reqs .append (greeter_protos .GreetingRequest (name = name ))
117+ i = 0
118+ for req in reqs :
119+ if i == 1 :
120+ service_daemon_instance .process .send_signal (SIGTERM )
121+ i += 1
122+ await asyncio .sleep (sleep )
123+ yield req
124+
125+
126+ async def update_graceful_shutdown_headers (service_client , dynamic_config , headers_enabled , headers ):
127+ dynamic_config .set_values ({'GRACEFUL_SHUTDOWN_HEADERS' : {'enabled' : headers_enabled , 'headers' : headers }})
128+ await service_client .update_server_state ()
129+
130+
55131def check_present (metadata , headers : dict [str , list [str ]]):
56132 metadata_dict = to_dict (metadata )
57133 for k , v in headers .items ():
0 commit comments