Skip to content

Commit de1c82e

Browse files
author
lexeyo
committed
feat grpc: enable graceful shutdown headers middleware in gRPC health service
commit_hash:5aa1b221e4906f90169c20a7b7e114dcc09c71d7
1 parent 05d2a64 commit de1c82e

File tree

5 files changed

+93
-1
lines changed

5 files changed

+93
-1
lines changed

.mapping.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,6 +2387,8 @@
23872387
"grpc/handlers/functional_tests/health/CMakeLists.txt":"taxi/uservices/userver/grpc/handlers/functional_tests/health/CMakeLists.txt",
23882388
"grpc/handlers/functional_tests/health/service.cpp":"taxi/uservices/userver/grpc/handlers/functional_tests/health/service.cpp",
23892389
"grpc/handlers/functional_tests/health/static_config.yaml":"taxi/uservices/userver/grpc/handlers/functional_tests/health/static_config.yaml",
2390+
"grpc/handlers/functional_tests/health/tests-graceful-shutdown/conftest.py":"taxi/uservices/userver/grpc/handlers/functional_tests/health/tests-graceful-shutdown/conftest.py",
2391+
"grpc/handlers/functional_tests/health/tests-graceful-shutdown/test_graceful_shutdown.py":"taxi/uservices/userver/grpc/handlers/functional_tests/health/tests-graceful-shutdown/test_graceful_shutdown.py",
23902392
"grpc/handlers/functional_tests/health/tests/conftest.py":"taxi/uservices/userver/grpc/handlers/functional_tests/health/tests/conftest.py",
23912393
"grpc/handlers/functional_tests/health/tests/grpcserver/test_grpcserver.py":"taxi/uservices/userver/grpc/handlers/functional_tests/health/tests/grpcserver/test_grpcserver.py",
23922394
"grpc/handlers/include/userver/ugrpc/server/health/component.hpp":"taxi/uservices/userver/grpc/handlers/include/userver/ugrpc/server/health/component.hpp",

grpc/handlers/functional_tests/health/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,11 @@ target_link_libraries(${PROJECT_NAME} userver-grpc-handlers)
55

66
include(UserverGrpcTargets)
77

8-
userver_chaos_testsuite_add(PYTHONPATH "${CMAKE_CURRENT_BINARY_DIR}/../../proto")
8+
userver_chaos_testsuite_add(
9+
TESTS_DIRECTORY tests
10+
PYTHONPATH "${CMAKE_CURRENT_BINARY_DIR}/../../proto"
11+
)
12+
userver_chaos_testsuite_add(
13+
TESTS_DIRECTORY tests-graceful-shutdown
14+
PYTHONPATH "${CMAKE_CURRENT_BINARY_DIR}/../../proto"
15+
)

grpc/handlers/functional_tests/health/static_config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# yaml
22
components_manager:
3+
graceful_shutdown_interval: 10s
4+
35
components:
46
# The required common components
57
logging:
@@ -25,6 +27,9 @@ components_manager:
2527
grpc-health:
2628
task-processor: main-task-processor
2729
disable-all-pipeline-middlewares: true
30+
middlewares:
31+
grpc-server-graceful-shutdown-headers:
32+
enabled: true
2833

2934
default_task_processor: main-task-processor
3035

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import pytest
2+
3+
try:
4+
from src.proto.grpc.health.v1 import health_pb2_grpc
5+
except ImportError:
6+
from health.v1 import health_pb2_grpc
7+
8+
pytest_plugins = ['pytest_userver.plugins.grpc']
9+
10+
11+
@pytest.fixture
12+
def grpc_client(grpc_channel):
13+
return health_pb2_grpc.HealthStub(grpc_channel)
14+
15+
16+
@pytest.fixture(name='userver_config_testsuite', scope='session')
17+
def _userver_config_testsuite(userver_config_testsuite):
18+
def patch_config(config, config_vars) -> None:
19+
userver_config_testsuite(config, config_vars)
20+
# Restore the option after it's deleted by the base fixture.
21+
# Don't do this in your testsuite tests! For userver tests only.
22+
config['components_manager']['graceful_shutdown_interval'] = '3s'
23+
24+
return patch_config
25+
26+
27+
@pytest.fixture(scope='session')
28+
def graceful_shutdown_headers() -> dict[str, list[str]]:
29+
return {'x-envoy-immediate-health-check-fail': ['true']}
30+
31+
32+
@pytest.fixture(scope='session')
33+
def dynamic_config_fallback_patch(graceful_shutdown_headers):
34+
return {'GRACEFUL_SHUTDOWN_HEADERS': {'enabled': True, 'headers': graceful_shutdown_headers}}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from signal import SIGTERM
2+
3+
import pytest
4+
5+
try:
6+
from src.proto.grpc.health.v1 import health_pb2
7+
except ImportError:
8+
from health.v1 import health_pb2
9+
10+
11+
@pytest.mark.uservice_oneshot
12+
async def test_graceful_shutdown_headers(service_daemon_instance, grpc_client, graceful_shutdown_headers):
13+
service_daemon_instance.process.send_signal(SIGTERM)
14+
15+
request = health_pb2.HealthCheckRequest()
16+
call = grpc_client.Check(request)
17+
response = await call
18+
assert response.status == health_pb2.HealthCheckResponse.NOT_SERVING
19+
20+
check_present(await call.initial_metadata(), graceful_shutdown_headers)
21+
check_not_present(await call.trailing_metadata(), graceful_shutdown_headers)
22+
23+
service_daemon_instance.process.wait()
24+
25+
26+
def check_present(metadata, headers: dict[str, list[str]]):
27+
metadata_dict = to_dict(metadata)
28+
for k, v in headers.items():
29+
assert k in metadata_dict
30+
assert metadata_dict[k] == v
31+
32+
33+
def check_not_present(metadata, headers: dict[str, list[str]]):
34+
metadata_dict = to_dict(metadata)
35+
for k in headers.keys():
36+
assert k not in metadata_dict
37+
38+
39+
def to_dict(metadata) -> dict[str, list[str]]:
40+
result: dict[str, list[str]] = {}
41+
for k, v in metadata:
42+
result.setdefault(k, []).append(v)
43+
44+
return result

0 commit comments

Comments
 (0)