Add resolver for binder transport URI scheme (#27529)

This commit is part of the effort to create binder channel with
GRPC_CLIENT_CHANNEL type.

The resolver will be used during name resolution, and the result will
later be used to identify the corresponding endpoint binder in
SubchannelConnector.

Besides the unit test, this change is tested with other changes locally
end to end on real device.
pull/27788/head
Ming-Chuan 3 years ago committed by GitHub
parent f72f778565
commit 34fdb542b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      BUILD
  2. 38
      CMakeLists.txt
  3. 2
      Makefile
  4. 11
      build_autogenerated.yaml
  5. 2
      config.m4
  6. 2
      config.w32
  7. 1
      gRPC-Core.podspec
  8. 1
      grpc.gemspec
  9. 2
      grpc.gyp
  10. 1
      package.xml
  11. 9
      src/core/ext/filters/client_channel/resolver/binder/README.md
  12. 139
      src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc
  13. 10
      src/core/plugin_registry/grpc_plugin_registry.cc
  14. 1
      src/python/grpcio/grpc_core_dependencies.py
  15. 14
      test/core/client_channel/resolvers/BUILD
  16. 181
      test/core/client_channel/resolvers/binder_resolver_test.cc
  17. 1
      tools/doxygen/Doxyfile.c++.internal
  18. 2
      tools/doxygen/Doxyfile.core.internal
  19. 24
      tools/run_tests/generated/tests.json

18
BUILD

@ -1928,6 +1928,7 @@ grpc_cc_library(
"grpc_resolver_fake",
"grpc_resolver_dns_native",
"grpc_resolver_sockaddr",
"grpc_resolver_binder",
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_server_insecure",
"grpc_transport_inproc",
@ -2968,6 +2969,23 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_resolver_binder",
srcs = [
"src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc",
],
external_deps = [
"absl/strings",
],
language = "c++",
deps = [
"gpr_base",
"grpc_base",
"grpc_client_channel",
"slice",
],
)
grpc_cc_library(
name = "grpc_resolver_fake",
srcs = ["src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc"],

38
CMakeLists.txt generated

@ -751,6 +751,7 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bdp_estimator_test)
endif()
add_dependencies(buildtests_cxx binder_resolver_test)
add_dependencies(buildtests_cxx binder_server_test)
add_dependencies(buildtests_cxx binder_transport_test)
add_dependencies(buildtests_cxx bitset_test)
@ -1529,6 +1530,7 @@ add_library(grpc
src/core/ext/filters/client_channel/local_subchannel_pool.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@ -2365,6 +2367,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/local_subchannel_pool.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@ -8295,6 +8298,41 @@ endif()
endif()
if(gRPC_BUILD_TESTS)
add_executable(binder_resolver_test
test/core/client_channel/resolvers/binder_resolver_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(binder_resolver_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(binder_resolver_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(binder_server_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc

2
Makefile generated

@ -1082,6 +1082,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/local_subchannel_pool.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
@ -1764,6 +1765,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/local_subchannel_pool.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \

@ -996,6 +996,7 @@ libs:
- src/core/ext/filters/client_channel/local_subchannel_pool.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@ -1968,6 +1969,7 @@ libs:
- src/core/ext/filters/client_channel/local_subchannel_pool.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@ -4609,6 +4611,15 @@ targets:
- posix
- mac
uses_polling: false
- name: binder_resolver_test
gtest: true
build: test
language: c++
headers: []
src:
- test/core/client_channel/resolvers/binder_resolver_test.cc
deps:
- grpc_test_util
- name: binder_server_test
gtest: true
build: test

2
config.m4 generated

@ -77,6 +77,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/local_subchannel_pool.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
@ -1074,6 +1075,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/weighted_target)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/binder)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native)

2
config.w32 generated

@ -43,6 +43,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\local_subchannel_pool.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\binder\\binder_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_event_engine.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " +
@ -1073,6 +1074,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\weighted_target");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\xds");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\binder");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native");

1
gRPC-Core.podspec generated

@ -257,6 +257,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc',

1
grpc.gemspec generated

@ -177,6 +177,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h )
s.files += %w( src/core/ext/filters/client_channel/resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc )

2
grpc.gyp generated

@ -523,6 +523,7 @@
'src/core/ext/filters/client_channel/local_subchannel_pool.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
@ -1180,6 +1181,7 @@
'src/core/ext/filters/client_channel/local_subchannel_pool.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',

1
package.xml generated

@ -157,6 +157,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc" role="src" />

@ -0,0 +1,9 @@
Support for resolving the scheme used by binder transport implementation.
The URI's authority is required to be empty.
The path is used as the identifiers of endpoint binder objects and the length
limit of the identifier is the same as unix socket length limit.
The length limit of the path should at least be 100 characters long. This is
guaranteed by `static_assert` in the implementation.

@ -0,0 +1,139 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
namespace grpc_core {
namespace {
class BinderResolver : public Resolver {
public:
BinderResolver(ServerAddressList addresses, ResolverArgs args)
: result_handler_(std::move(args.result_handler)),
addresses_(std::move(addresses)),
channel_args_(grpc_channel_args_copy(args.args)) {}
~BinderResolver() override { grpc_channel_args_destroy(channel_args_); };
void StartLocked() override {
Result result;
result.addresses = std::move(addresses_);
result.args = channel_args_;
channel_args_ = nullptr;
result_handler_->ReturnResult(std::move(result));
}
void ShutdownLocked() override {}
private:
std::unique_ptr<ResultHandler> result_handler_;
ServerAddressList addresses_;
const grpc_channel_args* channel_args_ = nullptr;
};
class BinderResolverFactory : public ResolverFactory {
public:
bool IsValidUri(const URI& uri) const override {
return ParseUri(uri, nullptr);
}
OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
ServerAddressList addresses;
if (!ParseUri(args.uri, &addresses)) return nullptr;
return MakeOrphanable<BinderResolver>(std::move(addresses),
std::move(args));
}
const char* scheme() const override { return "binder"; }
private:
static grpc_error_handle BinderAddrPopulate(
absl::string_view path, grpc_resolved_address* resolved_addr) {
path = absl::StripPrefix(path, "/");
if (path.empty()) {
return GRPC_ERROR_CREATE_FROM_CPP_STRING("path is empty");
}
// Store parsed path in a unix socket so it can be reinterpreted as
// sockaddr. An invalid address family (AF_MAX) is set to make sure it won't
// be accidentally used.
memset(resolved_addr, 0, sizeof(*resolved_addr));
struct sockaddr_un* un =
reinterpret_cast<struct sockaddr_un*>(resolved_addr->addr);
un->sun_family = AF_MAX;
static_assert(sizeof(un->sun_path) >= 101,
"unix socket path size is unexpectedly short");
if (path.size() + 1 > sizeof(un->sun_path)) {
return GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat(path, " is too long to be handled"));
}
// `un` has already be set to zero, no need to append null after the string
memcpy(un->sun_path, path.data(), path.size());
resolved_addr->len =
static_cast<socklen_t>(sizeof(un->sun_family) + path.size() + 1);
return GRPC_ERROR_NONE;
}
static bool ParseUri(const URI& uri, ServerAddressList* addresses) {
grpc_resolved_address addr;
{
if (!uri.authority().empty()) {
gpr_log(GPR_ERROR, "authority is not supported in binder scheme");
return false;
}
grpc_error_handle error = BinderAddrPopulate(uri.path(), &addr);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "%s", grpc_error_std_string(error).c_str());
GRPC_ERROR_UNREF(error);
return false;
}
}
if (addresses != nullptr) {
addresses->emplace_back(addr, nullptr /* args */);
}
return true;
}
};
} // namespace
} // namespace grpc_core
void grpc_resolver_binder_init() {
grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
absl::make_unique<grpc_core::BinderResolverFactory>());
}
void grpc_resolver_binder_shutdown() {}
#else
void grpc_resolver_binder_init() {}
void grpc_resolver_binder_shutdown() {}
#endif

@ -87,6 +87,11 @@ void GoogleCloud2ProdResolverShutdown();
} // namespace grpc_core
#endif
#ifdef GPR_SUPPORT_BINDER_TRANSPORT
void grpc_resolver_binder_init(void);
void grpc_resolver_binder_shutdown(void);
#endif
void grpc_register_built_in_plugins(void) {
grpc_register_plugin(grpc_chttp2_plugin_init, grpc_chttp2_plugin_shutdown);
grpc_register_plugin(grpc_core::ServiceConfigParserInit,
@ -136,6 +141,11 @@ void grpc_register_built_in_plugins(void) {
grpc_register_plugin(grpc_core::GoogleCloud2ProdResolverInit,
grpc_core::GoogleCloud2ProdResolverShutdown);
#endif
#ifdef GPR_SUPPORT_BINDER_TRANSPORT
grpc_register_plugin(grpc_resolver_binder_init,
grpc_resolver_binder_shutdown);
#endif
}
namespace grpc_core {

@ -52,6 +52,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/local_subchannel_pool.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',

@ -18,6 +18,20 @@ grpc_package(name = "test/core/client_channel/resolvers")
licenses(["notice"])
grpc_cc_test(
name = "binder_resolver_test",
srcs = ["binder_resolver_test.cc"],
external_deps = [
"gtest",
],
language = "C++",
deps = [
"//:gpr",
"//:grpc",
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "dns_resolver_connectivity_using_ares_test",
srcs = ["dns_resolver_connectivity_test.cc"],

@ -0,0 +1,181 @@
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <gtest/gtest.h>
#include "src/core/lib/iomgr/port.h"
#include "test/core/util/test_config.h"
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
#include <cstring>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
// Registers the factory with `grpc_core::ResolverRegistry`. Defined in
// binder_resolver.cc
void grpc_resolver_binder_init(void);
namespace {
class BinderResolverTest : public ::testing::Test {
public:
BinderResolverTest() {
factory_ = grpc_core::ResolverRegistry::LookupResolverFactory("binder");
}
~BinderResolverTest() override {}
static void SetUpTestSuite() {
grpc_init();
if (grpc_core::ResolverRegistry::LookupResolverFactory("binder") ==
nullptr) {
// Binder resolver will only be registered on platforms that support
// binder transport. If it is not registered on current platform, we
// manually register it here for testing purpose.
grpc_resolver_binder_init();
ASSERT_TRUE(grpc_core::ResolverRegistry::LookupResolverFactory("binder"));
}
}
static void TearDownTestSuite() { grpc_shutdown(); }
void SetUp() override { ASSERT_TRUE(factory_); }
class ResultHandler : public grpc_core::Resolver::ResultHandler {
public:
ResultHandler() = default;
explicit ResultHandler(const std::string& expected_binder_id)
: expect_result_(true), expected_binder_id_(expected_binder_id) {}
void ReturnResult(grpc_core::Resolver::Result result) override {
EXPECT_TRUE(expect_result_);
ASSERT_TRUE(result.addresses.size() == 1);
grpc_core::ServerAddress addr = result.addresses[0];
const struct sockaddr_un* un =
reinterpret_cast<const struct sockaddr_un*>(addr.address().addr);
EXPECT_EQ(addr.address().len,
sizeof(un->sun_family) + expected_binder_id_.length() + 1);
EXPECT_EQ(un->sun_family, AF_MAX);
EXPECT_EQ(un->sun_path, expected_binder_id_);
}
void ReturnError(grpc_error_handle error) override {
GRPC_ERROR_UNREF(error);
}
private:
// Whether we expect ReturnResult function to be invoked
bool expect_result_ = false;
std::string expected_binder_id_;
};
void TestSucceeds(const char* string, const std::string& expected_path) {
gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
factory_->scheme());
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
ASSERT_TRUE(uri.ok()) << uri.status().ToString();
grpc_core::ResolverArgs args;
args.uri = std::move(*uri);
args.result_handler =
absl::make_unique<BinderResolverTest::ResultHandler>(expected_path);
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
factory_->CreateResolver(std::move(args));
ASSERT_TRUE(resolver != nullptr);
resolver->StartLocked();
}
void TestFails(const char* string) {
gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
factory_->scheme());
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
ASSERT_TRUE(uri.ok()) << uri.status().ToString();
grpc_core::ResolverArgs args;
args.uri = std::move(*uri);
args.result_handler =
absl::make_unique<BinderResolverTest::ResultHandler>();
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
factory_->CreateResolver(std::move(args));
EXPECT_TRUE(resolver == nullptr);
}
private:
grpc_core::ResolverFactory* factory_;
};
} // namespace
// Authority is not allowed
TEST_F(BinderResolverTest, AuthorityPresents) {
TestFails("binder://example");
TestFails("binder://google.com");
TestFails("binder://google.com/test");
}
// Path cannot be empty
TEST_F(BinderResolverTest, EmptyPath) {
TestFails("binder:");
TestFails("binder:/");
TestFails("binder://");
}
TEST_F(BinderResolverTest, PathLength) {
// Note that we have a static assert in binder_resolver.cc that checks
// sizeof(sockaddr_un::sun_path) is greater than 100
// 100 character path should be fine
TestSucceeds(("binder:l" + std::string(98, 'o') + "g").c_str(),
"l" + std::string(98, 'o') + "g");
// 200 character path most likely will fail
TestFails(("binder:l" + std::string(198, 'o') + "g").c_str());
}
TEST_F(BinderResolverTest, SlashPrefixes) {
TestSucceeds("binder:///test", "test");
TestSucceeds("binder:////test", "/test");
}
TEST_F(BinderResolverTest, ValidCases) {
TestSucceeds("binder:[[", "[[");
TestSucceeds("binder:google!com", "google!com");
TestSucceeds("binder:test/", "test/");
TestSucceeds("binder:test:", "test:");
TestSucceeds("binder:e", "e");
TestSucceeds("binder:example", "example");
TestSucceeds("binder:google.com", "google.com");
TestSucceeds("binder:~", "~");
TestSucceeds("binder:12345", "12345");
TestSucceeds(
"binder:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._"
"~",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~");
}
#endif
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
return RUN_ALL_TESTS();
}

@ -1114,6 +1114,7 @@ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.h \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver.h \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc \

@ -939,6 +939,8 @@ src/core/ext/filters/client_channel/proxy_mapper_registry.h \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver.h \
src/core/ext/filters/client_channel/resolver/README.md \
src/core/ext/filters/client_channel/resolver/binder/README.md \
src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc \

@ -3379,6 +3379,30 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "binder_resolver_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save