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