• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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), &notification]() {
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), &notification);
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, &notification);
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, &notification);
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