OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/bind.h" | |
6 #include "net/dns/dns_response.h" | |
7 #include "net/dns/dns_test_util.h" | |
8 #include "net/dns/mdns_cache.h" | |
9 #include "net/dns/record_parsed.h" | |
10 #include "net/dns/record_rdata.h" | |
11 #include "testing/gmock/include/gmock/gmock.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 using ::testing::Return; | |
15 using ::testing::StrictMock; | |
16 | |
17 namespace net { | |
18 | |
19 static const uint8 kTestResponsesDifferentAnswers[] = { | |
20 // Answer 1 | |
21 // ghs.l.google.com in DNS format. | |
22 0x03, 'g', 'h', 's', | |
23 0x01, 'l', | |
24 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
25 0x03, 'c', 'o', 'm', | |
26 0x00, | |
27 0x00, 0x01, // TYPE is A. | |
28 0x00, 0x01, // CLASS is IN. | |
29 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
30 0x00, 0x35, | |
31 0x00, 0x04, // RDLENGTH is 4 bytes. | |
32 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
33 0x5f, 0x79, | |
34 | |
35 // Answer 2 | |
36 // Pointer to answer 1 | |
37 0xc0, 0x00, | |
38 0x00, 0x01, // TYPE is A. | |
39 0x00, 0x01, // CLASS is IN. | |
40 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
41 0x00, 0x35, | |
42 0x00, 0x04, // RDLENGTH is 4 bytes. | |
43 0x4a, 0x7d, // RDATA is the IP: 74.125.95.122 | |
44 0x5f, 0x80, | |
45 }; | |
46 | |
47 static const uint8 kTestResponsesSameAnswers[] = { | |
48 // Answer 1 | |
49 // ghs.l.google.com in DNS format. | |
50 0x03, 'g', 'h', 's', | |
51 0x01, 'l', | |
52 0x06, 'g', 'o', 'o', 'g', 'l', 'e', | |
53 0x03, 'c', 'o', 'm', | |
54 0x00, | |
55 0x00, 0x01, // TYPE is A. | |
56 0x00, 0x01, // CLASS is IN. | |
57 0x00, 0x00, // TTL (4 bytes) is 53 seconds. | |
58 0x00, 0x35, | |
59 0x00, 0x04, // RDLENGTH is 4 bytes. | |
60 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
61 0x5f, 0x79, | |
62 | |
63 // Answer 2 | |
64 // Pointer to answer 1 | |
65 0xc0, 0x00, | |
66 0x00, 0x01, // TYPE is A. | |
67 0x00, 0x01, // CLASS is IN. | |
68 0x00, 0x00, // TTL (4 bytes) is 112 seconds. | |
69 0x00, 0x70, | |
70 0x00, 0x04, // RDLENGTH is 4 bytes. | |
71 0x4a, 0x7d, // RDATA is the IP: 74.125.95.121 | |
72 0x5f, 0x79, | |
73 }; | |
74 | |
75 class RecordRemovalMock { | |
76 public: | |
77 MOCK_METHOD1(OnRecordRemoved, void(const RecordParsed*)); | |
78 }; | |
79 | |
80 class MDnsCacheTest : public ::testing::Test { | |
81 public: | |
82 MDnsCacheTest() | |
83 : default_time_(base::Time::FromDoubleT(1234.0)) {} | |
84 virtual ~MDnsCacheTest() {} | |
85 | |
86 protected: | |
87 base::Time default_time_; | |
88 StrictMock<RecordRemovalMock> record_removal_; | |
89 MDnsCache cache_; | |
90 }; | |
91 | |
92 // Test a single insert, corresponding lookup, and unsuccessful lookup. | |
93 TEST_F(MDnsCacheTest, InsertLookupSingle) { | |
94 DnsRecordParser parser(kT1ResponseDatagram, sizeof(kT1ResponseDatagram), | |
95 sizeof(dns_protocol::Header)); | |
96 parser.SkipQuestion(); | |
97 | |
98 scoped_ptr<const RecordParsed> record1; | |
99 scoped_ptr<const RecordParsed> record2; | |
100 std::vector<const RecordParsed*> results; | |
101 | |
102 record1 = RecordParsed::CreateFrom(&parser, default_time_); | |
103 record2 = RecordParsed::CreateFrom(&parser, default_time_); | |
104 | |
105 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass())); | |
106 | |
107 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass())); | |
108 | |
109 cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results, | |
110 default_time_); | |
111 | |
112 EXPECT_EQ(1u, results.size()); | |
113 EXPECT_EQ(default_time_, results.front()->time_created()); | |
114 | |
115 EXPECT_EQ("ghs.l.google.com", results.front()->name()); | |
116 | |
117 results.clear(); | |
118 cache_.FindDnsRecords(PtrRecordRdata::kType, "ghs.l.google.com", &results, | |
119 default_time_); | |
120 | |
121 EXPECT_EQ(0u, results.size()); | |
122 } | |
123 | |
124 // Test that records expire when their ttl has passed. | |
125 TEST_F(MDnsCacheTest, Expiration) { | |
126 DnsRecordParser parser(kT1ResponseDatagram, sizeof(kT1ResponseDatagram), | |
127 sizeof(dns_protocol::Header)); | |
128 parser.SkipQuestion(); | |
129 scoped_ptr<const RecordParsed> record1; | |
130 scoped_ptr<const RecordParsed> record2; | |
131 | |
132 std::vector<const RecordParsed*> results; | |
133 const RecordParsed* record_to_be_deleted; | |
134 | |
135 record1 = RecordParsed::CreateFrom(&parser, default_time_); | |
136 base::TimeDelta ttl1 = base::TimeDelta::FromSeconds(record1->ttl()); | |
137 | |
138 record2 = RecordParsed::CreateFrom(&parser, default_time_); | |
139 base::TimeDelta ttl2 = base::TimeDelta::FromSeconds(record2->ttl()); | |
140 record_to_be_deleted = record2.get(); | |
141 | |
142 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass())); | |
143 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass())); | |
144 | |
145 cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results, | |
146 default_time_); | |
147 | |
148 EXPECT_EQ(1u, results.size()); | |
149 | |
150 EXPECT_EQ(default_time_ + ttl2, cache_.next_expiration()); | |
151 | |
152 | |
153 cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results, | |
154 default_time_ + ttl2); | |
155 | |
156 EXPECT_EQ(0u, results.size()); | |
157 | |
158 EXPECT_CALL(record_removal_, OnRecordRemoved(record_to_be_deleted)); | |
159 | |
160 cache_.CleanupRecords(default_time_ + ttl2, base::Bind( | |
161 &RecordRemovalMock::OnRecordRemoved, base::Unretained(&record_removal_))); | |
162 | |
163 // To make sure that we've indeed removed them from the map, check no funny | |
164 // business happens once they're deleted for good. | |
165 | |
166 EXPECT_EQ(default_time_ + ttl1, cache_.next_expiration()); | |
167 cache_.FindDnsRecords(ARecordRdata::kType, "ghs.l.google.com", &results, | |
168 default_time_ + ttl2); | |
169 | |
170 EXPECT_EQ(0u, results.size()); | |
171 } | |
172 | |
173 // Test that a new record replacing one with the same identity (name/rrtype for | |
174 // unique records) causes the cache to output a "record changed" event. | |
175 TEST_F(MDnsCacheTest, RecordChange) { | |
176 DnsRecordParser parser(kTestResponsesDifferentAnswers, | |
177 sizeof(kTestResponsesDifferentAnswers), | |
178 0); | |
179 | |
180 scoped_ptr<const RecordParsed> record1; | |
181 scoped_ptr<const RecordParsed> record2; | |
182 std::vector<const RecordParsed*> results; | |
183 | |
184 record1 = RecordParsed::CreateFrom(&parser, default_time_); | |
185 record2 = RecordParsed::CreateFrom(&parser, default_time_); | |
186 | |
187 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass())); | |
188 EXPECT_EQ(MDnsCache::RecordChanged, | |
189 cache_.UpdateDnsRecord(record2.Pass())); | |
190 } | |
191 | |
192 // Test that a new record replacing an otherwise identical one already in the | |
193 // cache causes the cache to output a "no change" event. | |
194 TEST_F(MDnsCacheTest, RecordNoChange) { | |
195 DnsRecordParser parser(kTestResponsesSameAnswers, | |
196 sizeof(kTestResponsesSameAnswers), | |
197 0); | |
198 | |
199 scoped_ptr<const RecordParsed> record1; | |
200 scoped_ptr<const RecordParsed> record2; | |
201 std::vector<const RecordParsed*> results; | |
202 | |
203 record1 = RecordParsed::CreateFrom(&parser, default_time_); | |
204 record2 = RecordParsed::CreateFrom(&parser, default_time_ + | |
205 base::TimeDelta::FromSeconds(1)); | |
206 | |
207 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record1.Pass())); | |
208 EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(record2.Pass())); | |
209 } | |
210 | |
211 // Test that the next expiration time of the cache is updated properly on record | |
212 // insertion. | |
213 TEST_F(MDnsCacheTest, RecordPreemptExpirationTime) { | |
214 DnsRecordParser parser(kTestResponsesSameAnswers, | |
215 sizeof(kTestResponsesSameAnswers), | |
216 0); | |
217 | |
218 scoped_ptr<const RecordParsed> record1; | |
219 scoped_ptr<const RecordParsed> record2; | |
220 std::vector<const RecordParsed*> results; | |
221 | |
222 record1 = RecordParsed::CreateFrom(&parser, default_time_); | |
223 record2 = RecordParsed::CreateFrom(&parser, default_time_); | |
224 base::TimeDelta ttl1 = base::TimeDelta::FromSeconds(record1->ttl()); | |
225 base::TimeDelta ttl2 = base::TimeDelta::FromSeconds(record2->ttl()); | |
226 | |
227 EXPECT_EQ(base::Time(), cache_.next_expiration()); | |
228 EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(record2.Pass())); | |
229 EXPECT_EQ(default_time_ + ttl2, cache_.next_expiration()); | |
230 EXPECT_EQ(MDnsCache::NoChange, cache_.UpdateDnsRecord(record1.Pass())); | |
231 EXPECT_EQ(default_time_ + ttl1, cache_.next_expiration()); | |
232 } | |
233 } | |
szym
2013/05/21 22:09:05
please add // namespace net
and a blank line above
Noam Samuel
2013/05/21 23:00:56
Done.
| |
OLD | NEW |