xref: /aosp_15_r20/external/cronet/net/dns/host_resolver_internal_result_test_util.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/host_resolver_internal_result_test_util.h"
6 
7 #include <map>
8 #include <optional>
9 #include <ostream>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "base/check.h"
15 #include "base/json/json_writer.h"
16 #include "base/time/time.h"
17 #include "net/base/connection_endpoint_metadata.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/dns/host_resolver_internal_result.h"
21 #include "net/dns/https_record_rdata.h"
22 #include "net/dns/public/dns_query_type.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 namespace net {
27 
28 using ::testing::AllOf;
29 using ::testing::Eq;
30 using ::testing::MakeMatcher;
31 using ::testing::Matcher;
32 using ::testing::MatchResultListener;
33 using ::testing::PrintToString;
34 using ::testing::Property;
35 using ::testing::StringMatchResultListener;
36 
37 namespace {
38 
39 class HostResolverInternalResultBaseMatcher
40     : public ::testing::MatcherInterface<const HostResolverInternalResult&> {
41  public:
HostResolverInternalResultBaseMatcher(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher)42   HostResolverInternalResultBaseMatcher(
43       std::string expected_domain_name,
44       DnsQueryType expected_query_type,
45       HostResolverInternalResult::Source expected_source,
46       Matcher<std::optional<base::TimeTicks>> expiration_matcher,
47       Matcher<std::optional<base::Time>> timed_expiration_matcher)
48       : expected_domain_name_(std::move(expected_domain_name)),
49         expected_query_type_(expected_query_type),
50         expected_source_(expected_source),
51         expiration_matcher_(std::move(expiration_matcher)),
52         timed_expiration_matcher_(std::move(timed_expiration_matcher)) {}
53   ~HostResolverInternalResultBaseMatcher() override = default;
54 
MatchAndExplain(const HostResolverInternalResult & result,MatchResultListener * result_listener) const55   bool MatchAndExplain(const HostResolverInternalResult& result,
56                        MatchResultListener* result_listener) const override {
57     if (result.type() == GetSubtype()) {
58       *result_listener << "which is type ";
59       NameSubtype(*result_listener);
60     } else {
61       *result_listener << "which is not type ";
62       NameSubtype(*result_listener);
63       return false;
64     }
65 
66     StringMatchResultListener base_listener;
67     bool base_matches = MatchAndExplainBaseProperties(result, base_listener);
68     StringMatchResultListener subtype_listener;
69     bool subtype_matches =
70         MatchAndExplainSubtypeProperties(result, subtype_listener);
71 
72     // If only one part mismatches, just explain that.
73     if (!base_matches || subtype_matches) {
74       *result_listener << ", and " << base_listener.str();
75     }
76     if (!subtype_matches || base_matches) {
77       *result_listener << ", and " << subtype_listener.str();
78     }
79 
80     return base_matches && subtype_matches;
81   }
82 
DescribeTo(std::ostream * os) const83   void DescribeTo(std::ostream* os) const override {
84     *os << "matches ";
85     Describe(*os);
86   }
87 
DescribeNegationTo(std::ostream * os) const88   void DescribeNegationTo(std::ostream* os) const override {
89     *os << "does not match ";
90     Describe(*os);
91   }
92 
93  protected:
94   virtual HostResolverInternalResult::Type GetSubtype() const = 0;
95   virtual void NameSubtype(MatchResultListener& result_listener) const = 0;
96   virtual bool MatchAndExplainSubtypeProperties(
97       const HostResolverInternalResult& result,
98       MatchResultListener& result_listener) const = 0;
99   virtual void DescribeSubtype(std::ostream& os) const = 0;
100 
101  private:
MatchAndExplainBaseProperties(const HostResolverInternalResult & result,MatchResultListener & result_listener) const102   bool MatchAndExplainBaseProperties(
103       const HostResolverInternalResult& result,
104       MatchResultListener& result_listener) const {
105     return ExplainMatchResult(
106         AllOf(Property("domain_name", &HostResolverInternalResult::domain_name,
107                        Eq(expected_domain_name_)),
108               Property("query_type", &HostResolverInternalResult::query_type,
109                        Eq(expected_query_type_)),
110               Property("source", &HostResolverInternalResult::source,
111                        Eq(expected_source_)),
112               Property("expiration", &HostResolverInternalResult::expiration,
113                        expiration_matcher_),
114               Property("timed_expiration",
115                        &HostResolverInternalResult::timed_expiration,
116                        timed_expiration_matcher_)),
117         result, &result_listener);
118   }
119 
Describe(std::ostream & os) const120   void Describe(std::ostream& os) const {
121     os << "\n    HostResolverInternalResult {";
122     DescribeBase(os);
123     DescribeSubtype(os);
124     os << "\n    }\n";
125   }
126 
DescribeBase(std::ostream & os) const127   void DescribeBase(std::ostream& os) const {
128     StringMatchResultListener subtype_name_listener;
129     NameSubtype(subtype_name_listener);
130 
131     os << "\n      domain_name: \"" << expected_domain_name_
132        << "\"\n      query_type: " << kDnsQueryTypes.at(expected_query_type_)
133        << "\n      type: " << subtype_name_listener.str()
134        << "\n      source: " << static_cast<int>(expected_source_)
135        << "\n      expiration: " << PrintToString(expiration_matcher_)
136        << "\n      timed_expiration: "
137        << PrintToString(timed_expiration_matcher_);
138   }
139 
140   std::string expected_domain_name_;
141   DnsQueryType expected_query_type_;
142   HostResolverInternalResult::Source expected_source_;
143   Matcher<std::optional<base::TimeTicks>> expiration_matcher_;
144   Matcher<std::optional<base::Time>> timed_expiration_matcher_;
145 };
146 
147 class HostResolverInternalDataResultMatcher
148     : public HostResolverInternalResultBaseMatcher {
149  public:
HostResolverInternalDataResultMatcher(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,Matcher<std::vector<IPEndPoint>> endpoints_matcher,Matcher<std::vector<std::string>> strings_matcher,Matcher<std::vector<HostPortPair>> hosts_matcher)150   HostResolverInternalDataResultMatcher(
151       std::string expected_domain_name,
152       DnsQueryType expected_query_type,
153       HostResolverInternalResult::Source expected_source,
154       Matcher<std::optional<base::TimeTicks>> expiration_matcher,
155       Matcher<std::optional<base::Time>> timed_expiration_matcher,
156       Matcher<std::vector<IPEndPoint>> endpoints_matcher,
157       Matcher<std::vector<std::string>> strings_matcher,
158       Matcher<std::vector<HostPortPair>> hosts_matcher)
159       : HostResolverInternalResultBaseMatcher(
160             std::move(expected_domain_name),
161             expected_query_type,
162             expected_source,
163             std::move(expiration_matcher),
164             std::move(timed_expiration_matcher)),
165         endpoints_matcher_(std::move(endpoints_matcher)),
166         strings_matcher_(std::move(strings_matcher)),
167         hosts_matcher_(std::move(hosts_matcher)) {}
168 
169   ~HostResolverInternalDataResultMatcher() override = default;
170 
171   HostResolverInternalDataResultMatcher(
172       const HostResolverInternalDataResultMatcher&) = default;
173   HostResolverInternalDataResultMatcher& operator=(
174       const HostResolverInternalDataResultMatcher&) = default;
175   HostResolverInternalDataResultMatcher(
176       HostResolverInternalDataResultMatcher&&) = default;
177   HostResolverInternalDataResultMatcher& operator=(
178       HostResolverInternalDataResultMatcher&&) = default;
179 
180  protected:
GetSubtype() const181   HostResolverInternalResult::Type GetSubtype() const override {
182     return HostResolverInternalResult::Type::kData;
183   }
184 
NameSubtype(MatchResultListener & result_listener) const185   void NameSubtype(MatchResultListener& result_listener) const override {
186     result_listener << "kData";
187   }
188 
MatchAndExplainSubtypeProperties(const HostResolverInternalResult & result,MatchResultListener & result_listener) const189   bool MatchAndExplainSubtypeProperties(
190       const HostResolverInternalResult& result,
191       MatchResultListener& result_listener) const override {
192     return ExplainMatchResult(
193         AllOf(Property("endpoints", &HostResolverInternalDataResult::endpoints,
194                        endpoints_matcher_),
195               Property("strings", &HostResolverInternalDataResult::strings,
196                        strings_matcher_),
197               Property("hosts", &HostResolverInternalDataResult::hosts,
198                        hosts_matcher_)),
199         result.AsData(), &result_listener);
200   }
201 
DescribeSubtype(std::ostream & os) const202   void DescribeSubtype(std::ostream& os) const override {
203     os << "\n      endpoints: " << PrintToString(endpoints_matcher_)
204        << "\n      strings: " << PrintToString(strings_matcher_)
205        << "\n      hosts: " << PrintToString(hosts_matcher_);
206   }
207 
208  private:
209   Matcher<std::vector<IPEndPoint>> endpoints_matcher_;
210   Matcher<std::vector<std::string>> strings_matcher_;
211   Matcher<std::vector<HostPortPair>> hosts_matcher_;
212 };
213 
214 class HostResolverInternalMetadataResultMatcher
215     : public HostResolverInternalResultBaseMatcher {
216  public:
HostResolverInternalMetadataResultMatcher(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,Matcher<std::multimap<HttpsRecordPriority,ConnectionEndpointMetadata>> metadatas_matcher)217   HostResolverInternalMetadataResultMatcher(
218       std::string expected_domain_name,
219       DnsQueryType expected_query_type,
220       HostResolverInternalResult::Source expected_source,
221       Matcher<std::optional<base::TimeTicks>> expiration_matcher,
222       Matcher<std::optional<base::Time>> timed_expiration_matcher,
223       Matcher<std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>>
224           metadatas_matcher)
225       : HostResolverInternalResultBaseMatcher(
226             std::move(expected_domain_name),
227             expected_query_type,
228             expected_source,
229             std::move(expiration_matcher),
230             std::move(timed_expiration_matcher)),
231         metadatas_matcher_(std::move(metadatas_matcher)) {}
232 
233   ~HostResolverInternalMetadataResultMatcher() override = default;
234 
235   HostResolverInternalMetadataResultMatcher(
236       const HostResolverInternalMetadataResultMatcher&) = default;
237   HostResolverInternalMetadataResultMatcher& operator=(
238       const HostResolverInternalMetadataResultMatcher&) = default;
239   HostResolverInternalMetadataResultMatcher(
240       HostResolverInternalMetadataResultMatcher&&) = default;
241   HostResolverInternalMetadataResultMatcher& operator=(
242       HostResolverInternalMetadataResultMatcher&&) = default;
243 
244  protected:
GetSubtype() const245   HostResolverInternalResult::Type GetSubtype() const override {
246     return HostResolverInternalResult::Type::kMetadata;
247   }
248 
NameSubtype(MatchResultListener & result_listener) const249   void NameSubtype(MatchResultListener& result_listener) const override {
250     result_listener << "kMetadata";
251   }
252 
MatchAndExplainSubtypeProperties(const HostResolverInternalResult & result,MatchResultListener & result_listener) const253   bool MatchAndExplainSubtypeProperties(
254       const HostResolverInternalResult& result,
255       MatchResultListener& result_listener) const override {
256     return ExplainMatchResult(
257         Property("metadatas", &HostResolverInternalMetadataResult::metadatas,
258                  metadatas_matcher_),
259         result.AsMetadata(), &result_listener);
260   }
261 
DescribeSubtype(std::ostream & os) const262   void DescribeSubtype(std::ostream& os) const override {
263     os << "\n      metadatas: " << PrintToString(metadatas_matcher_);
264   }
265 
266  private:
267   Matcher<std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>>
268       metadatas_matcher_;
269 };
270 
271 class HostResolverInternalErrorResultMatcher
272     : public HostResolverInternalResultBaseMatcher {
273  public:
HostResolverInternalErrorResultMatcher(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,int expected_error)274   HostResolverInternalErrorResultMatcher(
275       std::string expected_domain_name,
276       DnsQueryType expected_query_type,
277       HostResolverInternalResult::Source expected_source,
278       Matcher<std::optional<base::TimeTicks>> expiration_matcher,
279       Matcher<std::optional<base::Time>> timed_expiration_matcher,
280       int expected_error)
281       : HostResolverInternalResultBaseMatcher(
282             std::move(expected_domain_name),
283             expected_query_type,
284             expected_source,
285             std::move(expiration_matcher),
286             std::move(timed_expiration_matcher)),
287         expected_error_(expected_error) {}
288 
289   ~HostResolverInternalErrorResultMatcher() override = default;
290 
291   HostResolverInternalErrorResultMatcher(
292       const HostResolverInternalErrorResultMatcher&) = default;
293   HostResolverInternalErrorResultMatcher& operator=(
294       const HostResolverInternalErrorResultMatcher&) = default;
295   HostResolverInternalErrorResultMatcher(
296       HostResolverInternalErrorResultMatcher&&) = default;
297   HostResolverInternalErrorResultMatcher& operator=(
298       HostResolverInternalErrorResultMatcher&&) = default;
299 
300  protected:
GetSubtype() const301   HostResolverInternalResult::Type GetSubtype() const override {
302     return HostResolverInternalResult::Type::kError;
303   }
304 
NameSubtype(MatchResultListener & result_listener) const305   void NameSubtype(MatchResultListener& result_listener) const override {
306     result_listener << "kError";
307   }
308 
MatchAndExplainSubtypeProperties(const HostResolverInternalResult & result,MatchResultListener & result_listener) const309   bool MatchAndExplainSubtypeProperties(
310       const HostResolverInternalResult& result,
311       MatchResultListener& result_listener) const override {
312     return ExplainMatchResult(
313         Property("error", &HostResolverInternalErrorResult::error,
314                  Eq(expected_error_)),
315         result.AsError(), &result_listener);
316   }
317 
DescribeSubtype(std::ostream & os) const318   void DescribeSubtype(std::ostream& os) const override {
319     os << "\n      error: " << expected_error_;
320   }
321 
322  private:
323   int expected_error_;
324 };
325 
326 class HostResolverInternalAliasResultMatcher
327     : public HostResolverInternalResultBaseMatcher {
328  public:
HostResolverInternalAliasResultMatcher(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,std::string expected_alias_target)329   HostResolverInternalAliasResultMatcher(
330       std::string expected_domain_name,
331       DnsQueryType expected_query_type,
332       HostResolverInternalResult::Source expected_source,
333       Matcher<std::optional<base::TimeTicks>> expiration_matcher,
334       Matcher<std::optional<base::Time>> timed_expiration_matcher,
335       std::string expected_alias_target)
336       : HostResolverInternalResultBaseMatcher(
337             std::move(expected_domain_name),
338             expected_query_type,
339             expected_source,
340             std::move(expiration_matcher),
341             std::move(timed_expiration_matcher)),
342         expected_alias_target_(std::move(expected_alias_target)) {}
343 
344   ~HostResolverInternalAliasResultMatcher() override = default;
345 
346   HostResolverInternalAliasResultMatcher(
347       const HostResolverInternalAliasResultMatcher&) = default;
348   HostResolverInternalAliasResultMatcher& operator=(
349       const HostResolverInternalAliasResultMatcher&) = default;
350   HostResolverInternalAliasResultMatcher(
351       HostResolverInternalAliasResultMatcher&&) = default;
352   HostResolverInternalAliasResultMatcher& operator=(
353       HostResolverInternalAliasResultMatcher&&) = default;
354 
355  protected:
GetSubtype() const356   HostResolverInternalResult::Type GetSubtype() const override {
357     return HostResolverInternalResult::Type::kAlias;
358   }
359 
NameSubtype(MatchResultListener & result_listener) const360   void NameSubtype(MatchResultListener& result_listener) const override {
361     result_listener << "kAlias";
362   }
363 
MatchAndExplainSubtypeProperties(const HostResolverInternalResult & result,MatchResultListener & result_listener) const364   bool MatchAndExplainSubtypeProperties(
365       const HostResolverInternalResult& result,
366       MatchResultListener& result_listener) const override {
367     return ExplainMatchResult(
368         Property("alias_target", &HostResolverInternalAliasResult::alias_target,
369                  Eq(expected_alias_target_)),
370         result.AsAlias(), &result_listener);
371   }
372 
DescribeSubtype(std::ostream & os) const373   void DescribeSubtype(std::ostream& os) const override {
374     os << "\n      target: \"" << expected_alias_target_ << "\"";
375   }
376 
377  private:
378   std::string expected_alias_target_;
379 };
380 
381 }  // namespace
382 
ExpectHostResolverInternalDataResult(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,Matcher<std::vector<IPEndPoint>> endpoints_matcher,Matcher<std::vector<std::string>> strings_matcher,Matcher<std::vector<HostPortPair>> hosts_matcher)383 Matcher<const HostResolverInternalResult&> ExpectHostResolverInternalDataResult(
384     std::string expected_domain_name,
385     DnsQueryType expected_query_type,
386     HostResolverInternalResult::Source expected_source,
387     Matcher<std::optional<base::TimeTicks>> expiration_matcher,
388     Matcher<std::optional<base::Time>> timed_expiration_matcher,
389     Matcher<std::vector<IPEndPoint>> endpoints_matcher,
390     Matcher<std::vector<std::string>> strings_matcher,
391     Matcher<std::vector<HostPortPair>> hosts_matcher) {
392   return MakeMatcher(new HostResolverInternalDataResultMatcher(
393       std::move(expected_domain_name), expected_query_type, expected_source,
394       std::move(expiration_matcher), std::move(timed_expiration_matcher),
395       std::move(endpoints_matcher), std::move(strings_matcher),
396       std::move(hosts_matcher)));
397 }
398 
399 testing::Matcher<const HostResolverInternalResult&>
ExpectHostResolverInternalMetadataResult(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,testing::Matcher<std::optional<base::TimeTicks>> expiration_matcher,testing::Matcher<std::optional<base::Time>> timed_expiration_matcher,testing::Matcher<std::multimap<HttpsRecordPriority,ConnectionEndpointMetadata>> metadatas_matcher)400 ExpectHostResolverInternalMetadataResult(
401     std::string expected_domain_name,
402     DnsQueryType expected_query_type,
403     HostResolverInternalResult::Source expected_source,
404     testing::Matcher<std::optional<base::TimeTicks>> expiration_matcher,
405     testing::Matcher<std::optional<base::Time>> timed_expiration_matcher,
406     testing::Matcher<
407         std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>>
408         metadatas_matcher) {
409   return MakeMatcher(new HostResolverInternalMetadataResultMatcher(
410       std::move(expected_domain_name), expected_query_type, expected_source,
411       std::move(expiration_matcher), std::move(timed_expiration_matcher),
412       std::move(metadatas_matcher)));
413 }
414 
415 Matcher<const HostResolverInternalResult&>
ExpectHostResolverInternalErrorResult(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,int expected_error)416 ExpectHostResolverInternalErrorResult(
417     std::string expected_domain_name,
418     DnsQueryType expected_query_type,
419     HostResolverInternalResult::Source expected_source,
420     Matcher<std::optional<base::TimeTicks>> expiration_matcher,
421     Matcher<std::optional<base::Time>> timed_expiration_matcher,
422     int expected_error) {
423   return MakeMatcher(new HostResolverInternalErrorResultMatcher(
424       std::move(expected_domain_name), expected_query_type, expected_source,
425       std::move(expiration_matcher), std::move(timed_expiration_matcher),
426       expected_error));
427 }
428 
429 Matcher<const HostResolverInternalResult&>
ExpectHostResolverInternalAliasResult(std::string expected_domain_name,DnsQueryType expected_query_type,HostResolverInternalResult::Source expected_source,Matcher<std::optional<base::TimeTicks>> expiration_matcher,Matcher<std::optional<base::Time>> timed_expiration_matcher,std::string expected_alias_target)430 ExpectHostResolverInternalAliasResult(
431     std::string expected_domain_name,
432     DnsQueryType expected_query_type,
433     HostResolverInternalResult::Source expected_source,
434     Matcher<std::optional<base::TimeTicks>> expiration_matcher,
435     Matcher<std::optional<base::Time>> timed_expiration_matcher,
436     std::string expected_alias_target) {
437   return MakeMatcher(new HostResolverInternalAliasResultMatcher(
438       std::move(expected_domain_name), expected_query_type, expected_source,
439       std::move(expiration_matcher), std::move(timed_expiration_matcher),
440       std::move(expected_alias_target)));
441 }
442 
operator <<(std::ostream & os,const HostResolverInternalResult & result)443 std::ostream& operator<<(std::ostream& os,
444                          const HostResolverInternalResult& result) {
445   std::string json_string;
446   CHECK(base::JSONWriter::Write(result.ToValue(), &json_string));
447   return os << json_string;
448 }
449 
450 }  // namespace net
451