-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[grpc]: fix ex_authz grpc client race condition #17619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cec90fa
68c1ab3
b1f6e1f
d7ca14f
4e1da1c
a8d9e2d
f940e29
c48535c
aea819b
4873dc9
691119a
9f5b439
b761e4c
9a5bef9
f15e520
b6126d0
9e5e4d5
e11520a
21c9094
acd1d3d
86577ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,54 +21,89 @@ namespace HttpFilters { | |
| namespace ExtAuthz { | ||
| namespace { | ||
|
|
||
| void expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion api_version) { | ||
| void expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion api_version, | ||
| std::string const& grpc_service_yaml) { | ||
| std::unique_ptr<TestDeprecatedV2Api> _deprecated_v2_api; | ||
| if (api_version != envoy::config::core::v3::ApiVersion::V3) { | ||
| _deprecated_v2_api = std::make_unique<TestDeprecatedV2Api>(); | ||
| } | ||
| std::string yaml = R"EOF( | ||
| transport_api_version: V3 | ||
| grpc_service: | ||
| google_grpc: | ||
| target_uri: ext_authz_server | ||
| stat_prefix: google | ||
| failure_mode_allow: false | ||
| transport_api_version: {} | ||
| )EOF"; | ||
|
|
||
| ExtAuthzFilterConfig factory; | ||
| ProtobufTypes::MessagePtr proto_config = factory.createEmptyConfigProto(); | ||
| TestUtility::loadFromYaml( | ||
| fmt::format(yaml, TestUtility::getVersionStringFromApiVersion(api_version)), *proto_config); | ||
| fmt::format(grpc_service_yaml, TestUtility::getVersionStringFromApiVersion(api_version)), | ||
| *proto_config); | ||
|
|
||
| testing::StrictMock<Server::Configuration::MockFactoryContext> context; | ||
| testing::StrictMock<Server::Configuration::MockServerFactoryContext> server_context; | ||
| EXPECT_CALL(context, getServerFactoryContext()) | ||
| .WillRepeatedly(testing::ReturnRef(server_context)); | ||
| EXPECT_CALL(context, messageValidationVisitor()); | ||
| EXPECT_CALL(context, clusterManager()); | ||
| EXPECT_CALL(context, clusterManager()).Times(2); | ||
| EXPECT_CALL(context, runtime()); | ||
| EXPECT_CALL(context, scope()).Times(2); | ||
| EXPECT_CALL(context, scope()).Times(3); | ||
|
|
||
| Http::FilterFactoryCb cb = factory.createFilterFactoryFromProto(*proto_config, "stats", context); | ||
| Http::MockFilterChainFactoryCallbacks filter_callback; | ||
| EXPECT_CALL(filter_callback, addStreamFilter(_)); | ||
| // Expect the raw async client to be created inside the callback. | ||
| // The creation of the filter callback is in main thread while the execution of callback is in | ||
| // worker thread. Because of the thread local cache of async client, it must be created in worker | ||
| // thread inside the callback. | ||
| EXPECT_CALL(context.cluster_manager_.async_client_manager_, getOrCreateRawAsyncClient(_, _, _, _)) | ||
| .WillOnce(Invoke( | ||
| [](const envoy::config::core::v3::GrpcService&, Stats::Scope&, bool, Grpc::CacheOption) { | ||
| return std::make_unique<NiceMock<Grpc::MockAsyncClient>>(); | ||
| })); | ||
|
|
||
| Http::FilterFactoryCb cb = factory.createFilterFactoryFromProto(*proto_config, "stats", context); | ||
| Http::MockFilterChainFactoryCallbacks filter_callback; | ||
| EXPECT_CALL(filter_callback, addStreamFilter(_)); | ||
| cb(filter_callback); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it may be useful to add test that calls cb on a separate thread and verifies that getOrCreateRawAsyncClient is called on that separate thread.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, test added. |
||
|
|
||
| Thread::ThreadPtr thread = Thread::threadFactoryForTest().createThread([&context, cb]() { | ||
| Http::MockFilterChainFactoryCallbacks filter_callback; | ||
| EXPECT_CALL(filter_callback, addStreamFilter(_)); | ||
| // Execute the filter factory callback in another thread. | ||
| EXPECT_CALL(context.cluster_manager_.async_client_manager_, | ||
| getOrCreateRawAsyncClient(_, _, _, _)) | ||
| .WillOnce(Invoke( | ||
| [](const envoy::config::core::v3::GrpcService&, Stats::Scope&, bool, | ||
| Grpc::CacheOption) { return std::make_unique<NiceMock<Grpc::MockAsyncClient>>(); })); | ||
| cb(filter_callback); | ||
| }); | ||
| thread->join(); | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| TEST(HttpExtAuthzConfigTest, CorrectProtoGrpc) { | ||
| TEST(HttpExtAuthzConfigTest, CorrectProtoGoogleGrpc) { | ||
| std::string google_grpc_service_yaml = R"EOF( | ||
| transport_api_version: V3 | ||
| grpc_service: | ||
| google_grpc: | ||
| target_uri: ext_authz_server | ||
| stat_prefix: google | ||
| failure_mode_allow: false | ||
| transport_api_version: {} | ||
| )EOF"; | ||
| #ifndef ENVOY_DISABLE_DEPRECATED_FEATURES | ||
| // TODO(chaoqin-li1123): clean this up when we move AUTO to V3 by default. | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::AUTO, google_grpc_service_yaml); | ||
| #endif | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::V3, google_grpc_service_yaml); | ||
| } | ||
|
|
||
| TEST(HttpExtAuthzConfigTest, CorrectProtoEnvoyGrpc) { | ||
| std::string envoy_grpc_service_yaml = R"EOF( | ||
| transport_api_version: V3 | ||
| grpc_service: | ||
| envoy_grpc: | ||
| cluster_name: ext_authz_server | ||
| failure_mode_allow: false | ||
| transport_api_version: {} | ||
| )EOF"; | ||
| #ifndef ENVOY_DISABLE_DEPRECATED_FEATURES | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::AUTO); | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::V2); | ||
| // TODO(chaoqin-li1123): clean this up when we move AUTO to V3 by default. | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::AUTO, envoy_grpc_service_yaml); | ||
| #endif | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::V3); | ||
| expectCorrectProtoGrpc(envoy::config::core::v3::ApiVersion::V3, envoy_grpc_service_yaml); | ||
| } | ||
|
|
||
| TEST(HttpExtAuthzConfigTest, CorrectProtoHttp) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.