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