1 //
2 //
3 // Copyright 2017 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include "src/core/resolver/fake/fake_resolver.h"
20
21 #include <grpc/grpc.h>
22 #include <inttypes.h>
23 #include <string.h>
24
25 #include <algorithm>
26 #include <functional>
27 #include <memory>
28 #include <string>
29 #include <type_traits>
30 #include <utility>
31 #include <vector>
32
33 #include "absl/container/inlined_vector.h"
34 #include "absl/status/statusor.h"
35 #include "absl/strings/str_format.h"
36 #include "absl/synchronization/notification.h"
37 #include "gtest/gtest.h"
38 #include "src/core/config/core_configuration.h"
39 #include "src/core/lib/address_utils/parse_address.h"
40 #include "src/core/lib/channel/channel_args.h"
41 #include "src/core/lib/event_engine/default_event_engine.h"
42 #include "src/core/lib/iomgr/exec_ctx.h"
43 #include "src/core/lib/iomgr/resolved_address.h"
44 #include "src/core/resolver/endpoint_addresses.h"
45 #include "src/core/resolver/resolver_factory.h"
46 #include "src/core/resolver/resolver_registry.h"
47 #include "src/core/util/debug_location.h"
48 #include "src/core/util/orphanable.h"
49 #include "src/core/util/ref_counted_ptr.h"
50 #include "src/core/util/uri.h"
51 #include "src/core/util/work_serializer.h"
52 #include "test/core/test_util/test_config.h"
53
54 namespace grpc_core {
55 namespace testing {
56
57 class FakeResolverTest : public ::testing::Test {
58 protected:
59 class ResultHandler : public Resolver::ResultHandler {
60 public:
SetExpectedAndNotification(Resolver::Result expected,absl::Notification * notification)61 void SetExpectedAndNotification(Resolver::Result expected,
62 absl::Notification* notification) {
63 MutexLock lock(&mu_);
64 ASSERT_EQ(notification_, nullptr);
65 expected_ = std::move(expected);
66 notification_ = notification;
67 }
68
ReportResult(Resolver::Result actual)69 void ReportResult(Resolver::Result actual) override {
70 MutexLock lock(&mu_);
71 ASSERT_NE(notification_, nullptr);
72 // TODO(roth): Check fields other than just the addresses.
73 // Note: No good way to compare result_health_callback.
74 ASSERT_TRUE(actual.addresses.ok());
75 ASSERT_EQ(actual.addresses->size(), expected_.addresses->size());
76 for (size_t i = 0; i < expected_.addresses->size(); ++i) {
77 ASSERT_EQ((*actual.addresses)[i], (*expected_.addresses)[i]);
78 }
79 notification_->Notify();
80 notification_ = nullptr;
81 }
82
83 private:
84 Mutex mu_;
85 Resolver::Result expected_ ABSL_GUARDED_BY(mu_);
86 absl::Notification* notification_ ABSL_GUARDED_BY(mu_) = nullptr;
87 };
88
BuildFakeResolver(std::shared_ptr<WorkSerializer> work_serializer,RefCountedPtr<FakeResolverResponseGenerator> response_generator,std::unique_ptr<Resolver::ResultHandler> result_handler)89 static OrphanablePtr<Resolver> BuildFakeResolver(
90 std::shared_ptr<WorkSerializer> work_serializer,
91 RefCountedPtr<FakeResolverResponseGenerator> response_generator,
92 std::unique_ptr<Resolver::ResultHandler> result_handler) {
93 ResolverFactory* factory =
94 CoreConfiguration::Get().resolver_registry().LookupResolverFactory(
95 "fake");
96 ResolverArgs args;
97 args.args = ChannelArgs().SetObject(std::move(response_generator));
98 args.work_serializer = std::move(work_serializer);
99 args.result_handler = std::move(result_handler);
100 return factory->CreateResolver(std::move(args));
101 }
102
103 // Create a new resolution containing 2 addresses.
CreateResolverResult()104 static Resolver::Result CreateResolverResult() {
105 static size_t test_counter = 0;
106 const size_t num_addresses = 2;
107 // Create address list.
108 EndpointAddressesList addresses;
109 for (size_t i = 0; i < num_addresses; ++i) {
110 std::string uri_string = absl::StrFormat(
111 "ipv4:127.0.0.1:100%" PRIuPTR, (test_counter * num_addresses) + i);
112 absl::StatusOr<URI> uri = URI::Parse(uri_string);
113 EXPECT_TRUE(uri.ok());
114 grpc_resolved_address address;
115 EXPECT_TRUE(grpc_parse_uri(*uri, &address));
116 addresses.emplace_back(address, ChannelArgs());
117 }
118 ++test_counter;
119 Resolver::Result result;
120 result.addresses = std::move(addresses);
121 return result;
122 }
123
CreateResolver()124 OrphanablePtr<Resolver> CreateResolver() {
125 result_handler_ = new ResultHandler();
126 return BuildFakeResolver(
127 work_serializer_, response_generator_,
128 std::unique_ptr<Resolver::ResultHandler>(result_handler_));
129 }
130
RunSynchronously(std::function<void ()> callback)131 void RunSynchronously(std::function<void()> callback) {
132 Notification notification;
133 work_serializer_->Run(
134 [callback = std::move(callback), ¬ification]() {
135 callback();
136 notification.Notify();
137 },
138 DEBUG_LOCATION);
139 notification.WaitForNotification();
140 }
141
142 ExecCtx exec_ctx_;
143 std::shared_ptr<WorkSerializer> work_serializer_ =
144 std::make_shared<WorkSerializer>(
145 grpc_event_engine::experimental::GetDefaultEventEngine());
146 RefCountedPtr<FakeResolverResponseGenerator> response_generator_ =
147 MakeRefCounted<FakeResolverResponseGenerator>();
148 ResultHandler* result_handler_ = nullptr;
149 };
150
TEST_F(FakeResolverTest,WaitForResolverSet)151 TEST_F(FakeResolverTest, WaitForResolverSet) {
152 EXPECT_FALSE(response_generator_->WaitForResolverSet(absl::Milliseconds(1)));
153 auto resolver = CreateResolver();
154 ASSERT_NE(resolver, nullptr);
155 EXPECT_TRUE(response_generator_->WaitForResolverSet(absl::Milliseconds(1)));
156 }
157
TEST_F(FakeResolverTest,ReturnResultBeforeResolverCreated)158 TEST_F(FakeResolverTest, ReturnResultBeforeResolverCreated) {
159 // Return result via response generator.
160 Resolver::Result result = CreateResolverResult();
161 response_generator_->SetResponseAsync(result);
162 // Create and start resolver.
163 auto resolver = CreateResolver();
164 ASSERT_NE(resolver, nullptr);
165 absl::Notification notification;
166 result_handler_->SetExpectedAndNotification(std::move(result), ¬ification);
167 RunSynchronously([resolver = resolver.get()] { resolver->StartLocked(); });
168 // Expect result.
169 ASSERT_TRUE(notification.WaitForNotificationWithTimeout(
170 absl::Seconds(5 * grpc_test_slowdown_factor())));
171 }
172
TEST_F(FakeResolverTest,ReturnResultBeforeResolverStarted)173 TEST_F(FakeResolverTest, ReturnResultBeforeResolverStarted) {
174 // Create resolver.
175 auto resolver = CreateResolver();
176 ASSERT_NE(resolver, nullptr);
177 Resolver::Result result = CreateResolverResult();
178 absl::Notification notification;
179 result_handler_->SetExpectedAndNotification(result, ¬ification);
180 // Return result via response generator.
181 response_generator_->SetResponseAsync(std::move(result));
182 // Start resolver.
183 RunSynchronously([resolver = resolver.get()] { resolver->StartLocked(); });
184 // Expect result.
185 ASSERT_TRUE(notification.WaitForNotificationWithTimeout(
186 absl::Seconds(5 * grpc_test_slowdown_factor())));
187 }
188
TEST_F(FakeResolverTest,ReturnResult)189 TEST_F(FakeResolverTest, ReturnResult) {
190 // Create and start resolver.
191 auto resolver = CreateResolver();
192 ASSERT_NE(resolver, nullptr);
193 RunSynchronously([resolver = resolver.get()] { resolver->StartLocked(); });
194 Resolver::Result result = CreateResolverResult();
195 absl::Notification notification;
196 result_handler_->SetExpectedAndNotification(result, ¬ification);
197 // Return result via response generator.
198 response_generator_->SetResponseAsync(std::move(result));
199 // Expect result.
200 ASSERT_TRUE(notification.WaitForNotificationWithTimeout(
201 absl::Seconds(5 * grpc_test_slowdown_factor())));
202 }
203
TEST_F(FakeResolverTest,WaitForReresolutionRequest)204 TEST_F(FakeResolverTest, WaitForReresolutionRequest) {
205 // Create and start resolver.
206 auto resolver = CreateResolver();
207 ASSERT_NE(resolver, nullptr);
208 RunSynchronously([resolver = resolver.get()] { resolver->StartLocked(); });
209 // No re-resolution requested yet.
210 EXPECT_FALSE(
211 response_generator_->WaitForReresolutionRequest(absl::Milliseconds(1)));
212 // Request re-resolution, then try again.
213 RunSynchronously(
214 [resolver = resolver.get()] { resolver->RequestReresolutionLocked(); });
215 EXPECT_TRUE(
216 response_generator_->WaitForReresolutionRequest(absl::Milliseconds(1)));
217 }
218
219 } // namespace testing
220 } // namespace grpc_core
221
main(int argc,char ** argv)222 int main(int argc, char** argv) {
223 grpc::testing::TestEnvironment env(&argc, argv);
224 ::testing::InitGoogleTest(&argc, argv);
225 grpc::testing::TestGrpcScope grpc_scope;
226 return RUN_ALL_TESTS();
227 }
228