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 <string.h>
20
21 #include <string>
22
23 #include "absl/strings/str_format.h"
24
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27
28 #include "src/core/ext/filters/client_channel/parse_address.h"
29 #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
30 #include "src/core/ext/filters/client_channel/resolver_registry.h"
31 #include "src/core/ext/filters/client_channel/server_address.h"
32 #include "src/core/lib/channel/channel_args.h"
33 #include "src/core/lib/gprpp/ref_counted_ptr.h"
34 #include "src/core/lib/iomgr/work_serializer.h"
35 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
36
37 #include "test/core/util/test_config.h"
38
39 class ResultHandler : public grpc_core::Resolver::ResultHandler {
40 public:
SetExpectedAndEvent(grpc_core::Resolver::Result expected,gpr_event * ev)41 void SetExpectedAndEvent(grpc_core::Resolver::Result expected,
42 gpr_event* ev) {
43 GPR_ASSERT(ev_ == nullptr);
44 expected_ = std::move(expected);
45 ev_ = ev;
46 }
47
ReturnResult(grpc_core::Resolver::Result actual)48 void ReturnResult(grpc_core::Resolver::Result actual) override {
49 GPR_ASSERT(ev_ != nullptr);
50 // We only check the addresses, because that's the only thing
51 // explicitly set by the test via
52 // FakeResolverResponseGenerator::SetResponse().
53 GPR_ASSERT(actual.addresses.size() == expected_.addresses.size());
54 for (size_t i = 0; i < expected_.addresses.size(); ++i) {
55 GPR_ASSERT(actual.addresses[i] == expected_.addresses[i]);
56 }
57 gpr_event_set(ev_, (void*)1);
58 ev_ = nullptr;
59 }
60
ReturnError(grpc_error *)61 void ReturnError(grpc_error* /*error*/) override {}
62
63 private:
64 grpc_core::Resolver::Result expected_;
65 gpr_event* ev_ = nullptr;
66 };
67
build_fake_resolver(std::shared_ptr<grpc_core::WorkSerializer> work_serializer,grpc_core::FakeResolverResponseGenerator * response_generator,std::unique_ptr<grpc_core::Resolver::ResultHandler> result_handler)68 static grpc_core::OrphanablePtr<grpc_core::Resolver> build_fake_resolver(
69 std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
70 grpc_core::FakeResolverResponseGenerator* response_generator,
71 std::unique_ptr<grpc_core::Resolver::ResultHandler> result_handler) {
72 grpc_core::ResolverFactory* factory =
73 grpc_core::ResolverRegistry::LookupResolverFactory("fake");
74 grpc_arg generator_arg =
75 grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
76 response_generator);
77 grpc_channel_args channel_args = {1, &generator_arg};
78 grpc_core::ResolverArgs args;
79 args.args = &channel_args;
80 args.work_serializer = std::move(work_serializer);
81 args.result_handler = std::move(result_handler);
82 grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
83 factory->CreateResolver(std::move(args));
84 return resolver;
85 }
86
87 // Create a new resolution containing 2 addresses.
create_new_resolver_result()88 static grpc_core::Resolver::Result create_new_resolver_result() {
89 static size_t test_counter = 0;
90 const size_t num_addresses = 2;
91 // Create address list.
92 grpc_core::Resolver::Result result;
93 for (size_t i = 0; i < num_addresses; ++i) {
94 std::string uri_string = absl::StrFormat("ipv4:127.0.0.1:100%" PRIuPTR,
95 test_counter * num_addresses + i);
96 grpc_uri* uri = grpc_uri_parse(uri_string.c_str(), true);
97 grpc_resolved_address address;
98 GPR_ASSERT(grpc_parse_uri(uri, &address));
99 absl::InlinedVector<grpc_arg, 2> args_to_add;
100 result.addresses.emplace_back(
101 address.addr, address.len,
102 grpc_channel_args_copy_and_add(nullptr, nullptr, 0));
103 grpc_uri_destroy(uri);
104 }
105 ++test_counter;
106 return result;
107 }
108
test_fake_resolver()109 static void test_fake_resolver() {
110 grpc_core::ExecCtx exec_ctx;
111 std::shared_ptr<grpc_core::WorkSerializer> work_serializer =
112 std::make_shared<grpc_core::WorkSerializer>();
113 // Create resolver.
114 ResultHandler* result_handler = new ResultHandler();
115 grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
116 response_generator =
117 grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>();
118 grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = build_fake_resolver(
119 work_serializer, response_generator.get(),
120 std::unique_ptr<grpc_core::Resolver::ResultHandler>(result_handler));
121 GPR_ASSERT(resolver.get() != nullptr);
122 resolver->StartLocked();
123 // Test 1: normal resolution.
124 // next_results != NULL, reresolution_results == NULL.
125 // Expected response is next_results.
126 gpr_log(GPR_INFO, "TEST 1");
127 grpc_core::Resolver::Result result = create_new_resolver_result();
128 gpr_event ev1;
129 gpr_event_init(&ev1);
130 result_handler->SetExpectedAndEvent(result, &ev1);
131 response_generator->SetResponse(std::move(result));
132 grpc_core::ExecCtx::Get()->Flush();
133 GPR_ASSERT(gpr_event_wait(&ev1, grpc_timeout_seconds_to_deadline(5)) !=
134 nullptr);
135 // Test 2: update resolution.
136 // next_results != NULL, reresolution_results == NULL.
137 // Expected response is next_results.
138 gpr_log(GPR_INFO, "TEST 2");
139 result = create_new_resolver_result();
140 gpr_event ev2;
141 gpr_event_init(&ev2);
142 result_handler->SetExpectedAndEvent(result, &ev2);
143 response_generator->SetResponse(std::move(result));
144 grpc_core::ExecCtx::Get()->Flush();
145 GPR_ASSERT(gpr_event_wait(&ev2, grpc_timeout_seconds_to_deadline(5)) !=
146 nullptr);
147 // Test 3: normal re-resolution.
148 // next_results == NULL, reresolution_results != NULL.
149 // Expected response is reresolution_results.
150 gpr_log(GPR_INFO, "TEST 3");
151 grpc_core::Resolver::Result reresolution_result =
152 create_new_resolver_result();
153 gpr_event ev3;
154 gpr_event_init(&ev3);
155 result_handler->SetExpectedAndEvent(reresolution_result, &ev3);
156 // Set reresolution_results.
157 // No result will be returned until re-resolution is requested.
158 response_generator->SetReresolutionResponse(reresolution_result);
159 grpc_core::ExecCtx::Get()->Flush();
160 // Trigger a re-resolution.
161 resolver->RequestReresolutionLocked();
162 grpc_core::ExecCtx::Get()->Flush();
163 GPR_ASSERT(gpr_event_wait(&ev3, grpc_timeout_seconds_to_deadline(5)) !=
164 nullptr);
165 // Test 4: repeat re-resolution.
166 // next_results == NULL, reresolution_results != NULL.
167 // Expected response is reresolution_results.
168 gpr_log(GPR_INFO, "TEST 4");
169 gpr_event ev4;
170 gpr_event_init(&ev4);
171 result_handler->SetExpectedAndEvent(std::move(reresolution_result), &ev4);
172 // Trigger a re-resolution.
173 resolver->RequestReresolutionLocked();
174 grpc_core::ExecCtx::Get()->Flush();
175 GPR_ASSERT(gpr_event_wait(&ev4, grpc_timeout_seconds_to_deadline(5)) !=
176 nullptr);
177 // Test 5: normal resolution.
178 // next_results != NULL, reresolution_results != NULL.
179 // Expected response is next_results.
180 gpr_log(GPR_INFO, "TEST 5");
181 result = create_new_resolver_result();
182 gpr_event ev5;
183 gpr_event_init(&ev5);
184 result_handler->SetExpectedAndEvent(result, &ev5);
185 response_generator->SetResponse(std::move(result));
186 grpc_core::ExecCtx::Get()->Flush();
187 GPR_ASSERT(gpr_event_wait(&ev5, grpc_timeout_seconds_to_deadline(5)) !=
188 nullptr);
189 // Test 6: no-op.
190 // Requesting a new resolution without setting the response shouldn't trigger
191 // the resolution callback.
192 gpr_log(GPR_INFO, "TEST 6");
193 gpr_event ev6;
194 gpr_event_init(&ev6);
195 result_handler->SetExpectedAndEvent(grpc_core::Resolver::Result(), &ev6);
196 GPR_ASSERT(gpr_event_wait(&ev6, grpc_timeout_milliseconds_to_deadline(100)) ==
197 nullptr);
198 // Clean up.
199 resolver.reset();
200 }
201
main(int argc,char ** argv)202 int main(int argc, char** argv) {
203 grpc::testing::TestEnvironment env(argc, argv);
204 grpc_init();
205
206 test_fake_resolver();
207
208 grpc_shutdown();
209 return 0;
210 }
211