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