xref: /aosp_15_r20/external/grpc-grpc/test/core/client_channel/resolvers/binder_resolver_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/status/status.h"
21 #include "absl/status/statusor.h"
22 #include "gtest/gtest.h"
23 
24 #include "src/core/lib/config/core_configuration.h"
25 #include "src/core/lib/gprpp/orphanable.h"
26 #include "src/core/lib/iomgr/port.h"
27 #include "src/core/lib/iomgr/resolved_address.h"
28 #include "src/core/lib/uri/uri_parser.h"
29 #include "src/core/resolver/endpoint_addresses.h"
30 #include "src/core/resolver/resolver.h"
31 #include "src/core/resolver/resolver_factory.h"
32 #include "test/core/util/test_config.h"
33 
34 #ifdef GRPC_HAVE_UNIX_SOCKET
35 
36 #ifdef GPR_WINDOWS
37 // clang-format off
38 #include <ws2def.h>
39 #include <afunix.h>
40 // clang-format on
41 #else
42 #include <sys/socket.h>
43 #include <sys/un.h>
44 #endif  // GPR_WINDOWS
45 
46 #include <grpc/grpc.h>
47 #include <grpc/support/log.h>
48 
49 #include "src/core/lib/iomgr/exec_ctx.h"
50 #include "src/core/resolver/resolver_registry.h"
51 
52 // Registers the factory with `grpc_core::ResolverRegistry`. Defined in
53 // binder_resolver.cc
54 namespace grpc_core {
55 void RegisterBinderResolver(CoreConfiguration::Builder* builder);
56 }
57 
58 namespace {
59 
60 class BinderResolverTest : public ::testing::Test {
61  public:
BinderResolverTest()62   BinderResolverTest() {
63     factory_ = grpc_core::CoreConfiguration::Get()
64                    .resolver_registry()
65                    .LookupResolverFactory("binder");
66   }
~BinderResolverTest()67   ~BinderResolverTest() override {}
SetUpTestSuite()68   static void SetUpTestSuite() {
69     builder_ =
70         std::make_unique<grpc_core::CoreConfiguration::WithSubstituteBuilder>(
71             [](grpc_core::CoreConfiguration::Builder* builder) {
72               BuildCoreConfiguration(builder);
73               if (!builder->resolver_registry()->HasResolverFactory("binder")) {
74                 // Binder resolver will only be registered on platforms that
75                 // support binder transport. If it is not registered on current
76                 // platform, we manually register it here for testing purpose.
77                 RegisterBinderResolver(builder);
78                 ASSERT_TRUE(
79                     builder->resolver_registry()->HasResolverFactory("binder"));
80               }
81             });
82     grpc_init();
83     if (grpc_core::CoreConfiguration::Get()
84             .resolver_registry()
85             .LookupResolverFactory("binder") == nullptr) {
86     }
87   }
TearDownTestSuite()88   static void TearDownTestSuite() {
89     grpc_shutdown();
90     builder_.reset();
91   }
92 
SetUp()93   void SetUp() override { ASSERT_TRUE(factory_); }
94 
95   class ResultHandler : public grpc_core::Resolver::ResultHandler {
96    public:
97     ResultHandler() = default;
98 
ResultHandler(const std::string & expected_binder_id)99     explicit ResultHandler(const std::string& expected_binder_id)
100         : expect_result_(true), expected_binder_id_(expected_binder_id) {}
101 
ReportResult(grpc_core::Resolver::Result result)102     void ReportResult(grpc_core::Resolver::Result result) override {
103       EXPECT_TRUE(expect_result_);
104       ASSERT_TRUE(result.addresses.ok());
105       ASSERT_EQ(result.addresses->size(), 1);
106       grpc_core::EndpointAddresses addr = (*result.addresses)[0];
107       const struct sockaddr_un* un =
108           reinterpret_cast<const struct sockaddr_un*>(addr.address().addr);
109       EXPECT_EQ(addr.address().len,
110                 sizeof(un->sun_family) + expected_binder_id_.length() + 1);
111       EXPECT_EQ(un->sun_family, AF_MAX);
112       EXPECT_EQ(un->sun_path, expected_binder_id_);
113     }
114 
115    private:
116     // Whether we expect ReportResult function to be invoked
117     bool expect_result_ = false;
118 
119     std::string expected_binder_id_;
120   };
121 
TestSucceeds(const char * string,const std::string & expected_path)122   void TestSucceeds(const char* string, const std::string& expected_path) {
123     gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
124             std::string(factory_->scheme()).c_str());
125     grpc_core::ExecCtx exec_ctx;
126     absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
127     ASSERT_TRUE(uri.ok()) << uri.status().ToString();
128     grpc_core::ResolverArgs args;
129     args.uri = std::move(*uri);
130     args.result_handler =
131         std::make_unique<BinderResolverTest::ResultHandler>(expected_path);
132     grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
133         factory_->CreateResolver(std::move(args));
134     ASSERT_TRUE(resolver != nullptr);
135     resolver->StartLocked();
136   }
137 
TestFails(const char * string)138   void TestFails(const char* string) {
139     gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
140             std::string(factory_->scheme()).c_str());
141     grpc_core::ExecCtx exec_ctx;
142     absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
143     ASSERT_TRUE(uri.ok()) << uri.status().ToString();
144     grpc_core::ResolverArgs args;
145     args.uri = std::move(*uri);
146     args.result_handler = std::make_unique<BinderResolverTest::ResultHandler>();
147     grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
148         factory_->CreateResolver(std::move(args));
149     EXPECT_TRUE(resolver == nullptr);
150   }
151 
152  private:
153   grpc_core::ResolverFactory* factory_;
154   static std::unique_ptr<grpc_core::CoreConfiguration::WithSubstituteBuilder>
155       builder_;
156 };
157 
158 std::unique_ptr<grpc_core::CoreConfiguration::WithSubstituteBuilder>
159     BinderResolverTest::builder_;
160 
161 }  // namespace
162 
163 // Authority is not allowed
TEST_F(BinderResolverTest,AuthorityPresents)164 TEST_F(BinderResolverTest, AuthorityPresents) {
165   TestFails("binder://example");
166   TestFails("binder://google.com");
167   TestFails("binder://google.com/test");
168 }
169 
170 // Path cannot be empty
TEST_F(BinderResolverTest,EmptyPath)171 TEST_F(BinderResolverTest, EmptyPath) {
172   TestFails("binder:");
173   TestFails("binder:/");
174   TestFails("binder://");
175 }
176 
TEST_F(BinderResolverTest,PathLength)177 TEST_F(BinderResolverTest, PathLength) {
178   // Note that we have a static assert in binder_resolver.cc that checks
179   // sizeof(sockaddr_un::sun_path) is greater than 100
180 
181   // 100 character path should be fine
182   TestSucceeds(("binder:l" + std::string(98, 'o') + "g").c_str(),
183                "l" + std::string(98, 'o') + "g");
184 
185   // 200 character path most likely will fail
186   TestFails(("binder:l" + std::string(198, 'o') + "g").c_str());
187 }
188 
TEST_F(BinderResolverTest,SlashPrefixes)189 TEST_F(BinderResolverTest, SlashPrefixes) {
190   TestSucceeds("binder:///test", "test");
191   TestSucceeds("binder:////test", "/test");
192 }
193 
TEST_F(BinderResolverTest,ValidCases)194 TEST_F(BinderResolverTest, ValidCases) {
195   TestSucceeds("binder:[[", "[[");
196   TestSucceeds("binder:google!com", "google!com");
197   TestSucceeds("binder:test/", "test/");
198   TestSucceeds("binder:test:", "test:");
199 
200   TestSucceeds("binder:e", "e");
201   TestSucceeds("binder:example", "example");
202   TestSucceeds("binder:google.com", "google.com");
203   TestSucceeds("binder:~", "~");
204   TestSucceeds("binder:12345", "12345");
205   TestSucceeds(
206       "binder:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._"
207       "~",
208       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~");
209 }
210 
211 #endif  // GRPC_HAVE_UNIX_SOCKET
212 
main(int argc,char ** argv)213 int main(int argc, char** argv) {
214   ::testing::InitGoogleTest(&argc, argv);
215   grpc::testing::TestEnvironment env(&argc, argv);
216   return RUN_ALL_TESTS();
217 }
218