xref: /aosp_15_r20/external/cronet/net/dns/mdns_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/dns/mdns_cache.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <algorithm>
8*6777b538SAndroid Build Coastguard Worker #include <utility>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/dns/dns_response.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/dns/dns_test_util.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/dns/record_parsed.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/dns/record_rdata.h"
16*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
17*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker using ::testing::Return;
20*6777b538SAndroid Build Coastguard Worker using ::testing::StrictMock;
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker namespace net {
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker static const uint8_t kTestResponsesDifferentAnswers[] = {
25*6777b538SAndroid Build Coastguard Worker     // Answer 1
26*6777b538SAndroid Build Coastguard Worker     // ghs.l.google.com in DNS format.
27*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
28*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
29*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
30*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
31*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
32*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,  // RDATA is the IP: 74.125.95.121
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker     // Answer 2
35*6777b538SAndroid Build Coastguard Worker     // Pointer to answer 1
36*6777b538SAndroid Build Coastguard Worker     0xc0, 0x00, 0x00, 0x01,  // TYPE is A.
37*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,              // CLASS is IN.
38*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,             // TTL (4 bytes) is 53 seconds.
39*6777b538SAndroid Build Coastguard Worker     0, 4,                    // RDLENGTH is 4 bytes.
40*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 122,        // RDATA is the IP: 74.125.95.122
41*6777b538SAndroid Build Coastguard Worker };
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker static const uint8_t kTestResponsesSameAnswers[] = {
44*6777b538SAndroid Build Coastguard Worker     // Answer 1
45*6777b538SAndroid Build Coastguard Worker     // ghs.l.google.com in DNS format.
46*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
47*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
48*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
49*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
50*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
51*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,  // RDATA is the IP: 74.125.95.121
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker     // Answer 2
54*6777b538SAndroid Build Coastguard Worker     // Pointer to answer 1
55*6777b538SAndroid Build Coastguard Worker     0xc0, 0x00, 0x00, 0x01,  // TYPE is A.
56*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,              // CLASS is IN.
57*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 112,            // TTL (4 bytes) is 112 seconds.
58*6777b538SAndroid Build Coastguard Worker     0, 4,                    // RDLENGTH is 4 bytes.
59*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,        // RDATA is the IP: 74.125.95.121
60*6777b538SAndroid Build Coastguard Worker };
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker static const uint8_t kTestResponseTwoRecords[] = {
63*6777b538SAndroid Build Coastguard Worker     // Answer 1
64*6777b538SAndroid Build Coastguard Worker     // ghs.l.google.com in DNS format. (A)
65*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
66*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
67*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
68*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
69*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
70*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,  // RDATA is the IP: 74.125.95.121
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker     // Answer 2
73*6777b538SAndroid Build Coastguard Worker     // ghs.l.google.com in DNS format. (AAAA)
74*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
75*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x1c,  // TYPE is AAA.
76*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
77*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
78*6777b538SAndroid Build Coastguard Worker     0, 16,             // RDLENGTH is 16 bytes.
79*6777b538SAndroid Build Coastguard Worker     0x4a, 0x7d, 0x4a, 0x7d, 0x5f, 0x79, 0x5f, 0x79, 0x5f, 0x79, 0x5f, 0x79,
80*6777b538SAndroid Build Coastguard Worker     0x5f, 0x79, 0x5f, 0x79,
81*6777b538SAndroid Build Coastguard Worker };
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker static const uint8_t kTestResponsesGoodbyePacket[] = {
84*6777b538SAndroid Build Coastguard Worker     // Answer 1
85*6777b538SAndroid Build Coastguard Worker     // ghs.l.google.com in DNS format. (Goodbye packet)
86*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
87*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
88*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
89*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 0,        // TTL (4 bytes) is zero.
90*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
91*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,  // RDATA is the IP: 74.125.95.121
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker     // Answer 2
94*6777b538SAndroid Build Coastguard Worker     // ghs.l.google.com in DNS format.
95*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
96*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
97*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
98*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
99*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
100*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,  // RDATA is the IP: 74.125.95.121
101*6777b538SAndroid Build Coastguard Worker };
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker static const uint8_t kTestResponsesDifferentCapitalization[] = {
104*6777b538SAndroid Build Coastguard Worker     // Answer 1
105*6777b538SAndroid Build Coastguard Worker     // GHS.l.google.com in DNS format.
106*6777b538SAndroid Build Coastguard Worker     3, 'G', 'H', 'S', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
107*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
108*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
109*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
110*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
111*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 121,  // RDATA is the IP: 74.125.95.121
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker     // Answer 2
114*6777b538SAndroid Build Coastguard Worker     // ghs.l.GOOGLE.com in DNS format.
115*6777b538SAndroid Build Coastguard Worker     3, 'g', 'h', 's', 1, 'l', 6, 'G', 'O', 'O', 'G', 'L', 'E', 3, 'c', 'o', 'm',
116*6777b538SAndroid Build Coastguard Worker     0x00, 0x00, 0x01,  // TYPE is A.
117*6777b538SAndroid Build Coastguard Worker     0x00, 0x01,        // CLASS is IN.
118*6777b538SAndroid Build Coastguard Worker     0, 0, 0, 53,       // TTL (4 bytes) is 53 seconds.
119*6777b538SAndroid Build Coastguard Worker     0, 4,              // RDLENGTH is 4 bytes.
120*6777b538SAndroid Build Coastguard Worker     74, 125, 95, 122,  // RDATA is the IP: 74.125.95.122
121*6777b538SAndroid Build Coastguard Worker };
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker class RecordRemovalMock {
124*6777b538SAndroid Build Coastguard Worker  public:
125*6777b538SAndroid Build Coastguard Worker   MOCK_METHOD1(OnRecordRemoved, void(const RecordParsed*));
126*6777b538SAndroid Build Coastguard Worker };
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker class MDnsCacheTest : public ::testing::Test {
129*6777b538SAndroid Build Coastguard Worker  public:
MDnsCacheTest()130*6777b538SAndroid Build Coastguard Worker   MDnsCacheTest()
131*6777b538SAndroid Build Coastguard Worker       : default_time_(base::Time::FromSecondsSinceUnixEpoch(1234.0)) {}
132*6777b538SAndroid Build Coastguard Worker   ~MDnsCacheTest() override = default;
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker  protected:
135*6777b538SAndroid Build Coastguard Worker   base::Time default_time_;
136*6777b538SAndroid Build Coastguard Worker   StrictMock<RecordRemovalMock> record_removal_;
137*6777b538SAndroid Build Coastguard Worker   MDnsCache cache_;
138*6777b538SAndroid Build Coastguard Worker };
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker // Test a single insert, corresponding lookup, and unsuccessful lookup.
TEST_F(MDnsCacheTest,InsertLookupSingle)141*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, InsertLookupSingle) {
142*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kT1ResponseDatagram, sizeof(kT1ResponseDatagram),
143*6777b538SAndroid Build Coastguard Worker                          sizeof(dns_protocol::Header), kT1RecordCount);
144*6777b538SAndroid Build Coastguard Worker   std::string dotted_qname;
145*6777b538SAndroid Build Coastguard Worker   uint16_t qtype;
146*6777b538SAndroid Build Coastguard Worker   parser.ReadQuestion(dotted_qname, qtype);
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
149*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
150*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
153*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_);
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results,
160*6777b538SAndroid Build Coastguard Worker                         default_time_);
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, results.size());
163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_, results.front()->time_created());
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("ghs.l.google.com", results.front()->name());
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   results.clear();
168*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(PtrRecordRdata::kType, "ghs.l.google.com", &results,
169*6777b538SAndroid Build Coastguard Worker                         default_time_);
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, results.size());
172*6777b538SAndroid Build Coastguard Worker }
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker // Test that records expire when their ttl has passed.
TEST_F(MDnsCacheTest,Expiration)175*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, Expiration) {
176*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kT1ResponseDatagram, sizeof(kT1ResponseDatagram),
177*6777b538SAndroid Build Coastguard Worker                          sizeof(dns_protocol::Header), kT1RecordCount);
178*6777b538SAndroid Build Coastguard Worker   std::string dotted_qname;
179*6777b538SAndroid Build Coastguard Worker   uint16_t qtype;
180*6777b538SAndroid Build Coastguard Worker   parser.ReadQuestion(dotted_qname, qtype);
181*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
182*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
185*6777b538SAndroid Build Coastguard Worker   const RecordParsed* record_to_be_deleted;
186*6777b538SAndroid Build Coastguard Worker 
187*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
188*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl1 = base::Seconds(record1->ttl());
189*6777b538SAndroid Build Coastguard Worker 
190*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_);
191*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl2 = base::Seconds(record2->ttl());
192*6777b538SAndroid Build Coastguard Worker   record_to_be_deleted = record2.get();
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
195*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results,
198*6777b538SAndroid Build Coastguard Worker                         default_time_);
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, results.size());
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_ + ttl2, cache_.next_expiration());
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results,
206*6777b538SAndroid Build Coastguard Worker                         default_time_ + ttl2);
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, results.size());
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker   EXPECT_CALL(record_removal_, OnRecordRemoved(record_to_be_deleted));
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker   cache_.CleanupRecords(
213*6777b538SAndroid Build Coastguard Worker       default_time_ + ttl2,
214*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&RecordRemovalMock::OnRecordRemoved,
215*6777b538SAndroid Build Coastguard Worker                           base::Unretained(&record_removal_)));
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   // To make sure that we've indeed removed them from the map, check no funny
218*6777b538SAndroid Build Coastguard Worker   // business happens once they're deleted for good.
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_ + ttl1, cache_.next_expiration());
221*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results,
222*6777b538SAndroid Build Coastguard Worker                         default_time_ + ttl2);
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, results.size());
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker 
227*6777b538SAndroid Build Coastguard Worker // Test that a new record replacing one with the same identity (name/rrtype for
228*6777b538SAndroid Build Coastguard Worker // unique records) causes the cache to output a "record changed" event.
TEST_F(MDnsCacheTest,RecordChange)229*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, RecordChange) {
230*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponsesDifferentAnswers,
231*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponsesDifferentAnswers), 0,
232*6777b538SAndroid Build Coastguard Worker                          /*num_records=*/2);
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
235*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
236*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
239*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_);
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
242*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordChanged,
243*6777b538SAndroid Build Coastguard Worker             cache_.UpdateDnsRecord(std::move(record2)));
244*6777b538SAndroid Build Coastguard Worker }
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker // Test that a new record replacing an otherwise identical one already in the
247*6777b538SAndroid Build Coastguard Worker // cache causes the cache to output a "no change" event.
TEST_F(MDnsCacheTest,RecordNoChange)248*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, RecordNoChange) {
249*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponsesSameAnswers,
250*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponsesSameAnswers), 0,
251*6777b538SAndroid Build Coastguard Worker                          /*num_records=*/2);
252*6777b538SAndroid Build Coastguard Worker 
253*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
254*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
255*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
258*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_ + base::Seconds(1));
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
261*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(std::move(record2)));
262*6777b538SAndroid Build Coastguard Worker }
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker // Test that the next expiration time of the cache is updated properly on record
265*6777b538SAndroid Build Coastguard Worker // insertion.
TEST_F(MDnsCacheTest,RecordPreemptExpirationTime)266*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, RecordPreemptExpirationTime) {
267*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponsesSameAnswers,
268*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponsesSameAnswers), 0,
269*6777b538SAndroid Build Coastguard Worker                          /*num_records=*/2);
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
272*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
273*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
276*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_);
277*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl1 = base::Seconds(record1->ttl());
278*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl2 = base::Seconds(record2->ttl());
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Time(), cache_.next_expiration());
281*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
282*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_ + ttl2, cache_.next_expiration());
283*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(std::move(record1)));
284*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_ + ttl1, cache_.next_expiration());
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker 
287*6777b538SAndroid Build Coastguard Worker // Test that the cache handles mDNS "goodbye" packets correctly, not adding the
288*6777b538SAndroid Build Coastguard Worker // records to the cache if they are not already there, and eventually removing
289*6777b538SAndroid Build Coastguard Worker // records from the cache if they are.
TEST_F(MDnsCacheTest,GoodbyePacket)290*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, GoodbyePacket) {
291*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponsesGoodbyePacket,
292*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponsesGoodbyePacket), 0,
293*6777b538SAndroid Build Coastguard Worker                          /*num_records=*/2);
294*6777b538SAndroid Build Coastguard Worker 
295*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record_goodbye;
296*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record_hello;
297*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record_goodbye2;
298*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker   record_goodbye = RecordParsed::CreateFrom(&parser, default_time_);
301*6777b538SAndroid Build Coastguard Worker   record_hello = RecordParsed::CreateFrom(&parser, default_time_);
302*6777b538SAndroid Build Coastguard Worker   parser = DnsRecordParser(kTestResponsesGoodbyePacket,
303*6777b538SAndroid Build Coastguard Worker                            sizeof(kTestResponsesGoodbyePacket), 0,
304*6777b538SAndroid Build Coastguard Worker                            /*num_records=*/2);
305*6777b538SAndroid Build Coastguard Worker   record_goodbye2 = RecordParsed::CreateFrom(&parser, default_time_);
306*6777b538SAndroid Build Coastguard Worker 
307*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(record_hello->ttl());
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Time(), cache_.next_expiration());
310*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::NoChange,
311*6777b538SAndroid Build Coastguard Worker             cache_.UpdateDnsRecord(std::move(record_goodbye)));
312*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Time(), cache_.next_expiration());
313*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded,
314*6777b538SAndroid Build Coastguard Worker             cache_.UpdateDnsRecord(std::move(record_hello)));
315*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_ + ttl, cache_.next_expiration());
316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::NoChange,
317*6777b538SAndroid Build Coastguard Worker             cache_.UpdateDnsRecord(std::move(record_goodbye2)));
318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_ + base::Seconds(1), cache_.next_expiration());
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker 
TEST_F(MDnsCacheTest,AnyRRType)321*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, AnyRRType) {
322*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponseTwoRecords,
323*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponseTwoRecords), 0, /*num_records=*/2);
324*6777b538SAndroid Build Coastguard Worker 
325*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
326*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
327*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
330*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_);
331*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
332*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(0, "ghs.l.google.com", &results, default_time_);
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, results.size());
337*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(default_time_, results.front()->time_created());
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("ghs.l.google.com", results[0]->name());
340*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("ghs.l.google.com", results[1]->name());
341*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(dns_protocol::kTypeA,
342*6777b538SAndroid Build Coastguard Worker             std::min(results[0]->type(), results[1]->type()));
343*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(dns_protocol::kTypeAAAA,
344*6777b538SAndroid Build Coastguard Worker             std::max(results[0]->type(), results[1]->type()));
345*6777b538SAndroid Build Coastguard Worker }
346*6777b538SAndroid Build Coastguard Worker 
TEST_F(MDnsCacheTest,RemoveRecord)347*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, RemoveRecord) {
348*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kT1ResponseDatagram, sizeof(kT1ResponseDatagram),
349*6777b538SAndroid Build Coastguard Worker                          sizeof(dns_protocol::Header), kT1RecordCount);
350*6777b538SAndroid Build Coastguard Worker   std::string dotted_qname;
351*6777b538SAndroid Build Coastguard Worker   uint16_t qtype;
352*6777b538SAndroid Build Coastguard Worker   parser.ReadQuestion(dotted_qname, qtype);
353*6777b538SAndroid Build Coastguard Worker 
354*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
355*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
356*6777b538SAndroid Build Coastguard Worker 
357*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
358*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(dns_protocol::kTypeCNAME, "codereview.chromium.org",
361*6777b538SAndroid Build Coastguard Worker                         &results, default_time_);
362*6777b538SAndroid Build Coastguard Worker 
363*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, results.size());
364*6777b538SAndroid Build Coastguard Worker 
365*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record_out =
366*6777b538SAndroid Build Coastguard Worker       cache_.RemoveRecord(results.front());
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(record_out.get(), results.front());
369*6777b538SAndroid Build Coastguard Worker 
370*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(dns_protocol::kTypeCNAME, "codereview.chromium.org",
371*6777b538SAndroid Build Coastguard Worker                         &results, default_time_);
372*6777b538SAndroid Build Coastguard Worker 
373*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, results.size());
374*6777b538SAndroid Build Coastguard Worker }
375*6777b538SAndroid Build Coastguard Worker 
TEST_F(MDnsCacheTest,IsCacheOverfilled)376*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, IsCacheOverfilled) {
377*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponseTwoRecords,
378*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponseTwoRecords), 0, /*num_records=*/2);
379*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1 =
380*6777b538SAndroid Build Coastguard Worker       RecordParsed::CreateFrom(&parser, default_time_);
381*6777b538SAndroid Build Coastguard Worker   const RecordParsed* record1_ptr = record1.get();
382*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2 =
383*6777b538SAndroid Build Coastguard Worker       RecordParsed::CreateFrom(&parser, default_time_);
384*6777b538SAndroid Build Coastguard Worker 
385*6777b538SAndroid Build Coastguard Worker   cache_.set_entry_limit_for_testing(1);
386*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
387*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache_.IsCacheOverfilled());
388*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
389*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache_.IsCacheOverfilled());
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   record1 = cache_.RemoveRecord(record1_ptr);
392*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(record1);
393*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache_.IsCacheOverfilled());
394*6777b538SAndroid Build Coastguard Worker }
395*6777b538SAndroid Build Coastguard Worker 
TEST_F(MDnsCacheTest,ClearOnOverfilledCleanup)396*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, ClearOnOverfilledCleanup) {
397*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponseTwoRecords,
398*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponseTwoRecords), 0, /*num_records=*/2);
399*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1 =
400*6777b538SAndroid Build Coastguard Worker       RecordParsed::CreateFrom(&parser, default_time_);
401*6777b538SAndroid Build Coastguard Worker   const RecordParsed* record1_ptr = record1.get();
402*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2 =
403*6777b538SAndroid Build Coastguard Worker       RecordParsed::CreateFrom(&parser, default_time_);
404*6777b538SAndroid Build Coastguard Worker   const RecordParsed* record2_ptr = record2.get();
405*6777b538SAndroid Build Coastguard Worker 
406*6777b538SAndroid Build Coastguard Worker   cache_.set_entry_limit_for_testing(1);
407*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
408*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record2)));
409*6777b538SAndroid Build Coastguard Worker 
410*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache_.IsCacheOverfilled());
411*6777b538SAndroid Build Coastguard Worker 
412*6777b538SAndroid Build Coastguard Worker   // Expect everything to be removed on CleanupRecords() with overfilled cache.
413*6777b538SAndroid Build Coastguard Worker   EXPECT_CALL(record_removal_, OnRecordRemoved(record1_ptr));
414*6777b538SAndroid Build Coastguard Worker   EXPECT_CALL(record_removal_, OnRecordRemoved(record2_ptr));
415*6777b538SAndroid Build Coastguard Worker   cache_.CleanupRecords(
416*6777b538SAndroid Build Coastguard Worker       default_time_, base::BindRepeating(&RecordRemovalMock::OnRecordRemoved,
417*6777b538SAndroid Build Coastguard Worker                                          base::Unretained(&record_removal_)));
418*6777b538SAndroid Build Coastguard Worker 
419*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache_.IsCacheOverfilled());
420*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
421*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(dns_protocol::kTypeA, "ghs.l.google.com", &results,
422*6777b538SAndroid Build Coastguard Worker                         default_time_);
423*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(results.empty());
424*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(dns_protocol::kTypeAAAA, "ghs.l.google.com", &results,
425*6777b538SAndroid Build Coastguard Worker                         default_time_);
426*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(results.empty());
427*6777b538SAndroid Build Coastguard Worker }
428*6777b538SAndroid Build Coastguard Worker 
TEST_F(MDnsCacheTest,CaseInsensitive)429*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsCacheTest, CaseInsensitive) {
430*6777b538SAndroid Build Coastguard Worker   DnsRecordParser parser(kTestResponsesDifferentCapitalization,
431*6777b538SAndroid Build Coastguard Worker                          sizeof(kTestResponsesDifferentCapitalization), 0,
432*6777b538SAndroid Build Coastguard Worker                          /*num_records=*/2);
433*6777b538SAndroid Build Coastguard Worker 
434*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record1;
435*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<const RecordParsed> record2;
436*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results;
437*6777b538SAndroid Build Coastguard Worker 
438*6777b538SAndroid Build Coastguard Worker   record1 = RecordParsed::CreateFrom(&parser, default_time_);
439*6777b538SAndroid Build Coastguard Worker   record2 = RecordParsed::CreateFrom(&parser, default_time_);
440*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
441*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MDnsCache::RecordChanged,
442*6777b538SAndroid Build Coastguard Worker             cache_.UpdateDnsRecord(std::move(record2)));
443*6777b538SAndroid Build Coastguard Worker 
444*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(0, "ghs.l.google.com", &results, default_time_);
445*6777b538SAndroid Build Coastguard Worker 
446*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, results.size());
447*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("ghs.l.GOOGLE.com", results[0]->name());
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   std::vector<const RecordParsed*> results2;
450*6777b538SAndroid Build Coastguard Worker   cache_.FindDnsRecords(0, "GHS.L.google.COM", &results2, default_time_);
451*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(results, results2);
452*6777b538SAndroid Build Coastguard Worker }
453*6777b538SAndroid Build Coastguard Worker 
454*6777b538SAndroid Build Coastguard Worker }  // namespace net
455