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 <memory>
6*6777b538SAndroid Build Coastguard Worker #include <utility>
7*6777b538SAndroid Build Coastguard Worker #include <vector>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/simple_test_clock.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/time/clock.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/time/default_clock.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/timer/mock_timer.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h"
21*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/address_family.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_repeating_callback.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_address.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/base/rand_callback.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/base/test_completion_callback.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/dns/mdns_client_impl.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/dns/mock_mdns_socket_factory.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/dns/record_rdata.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/socket/udp_client_socket.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/test/test_with_task_environment.h"
34*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
35*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
36*6777b538SAndroid Build Coastguard Worker
37*6777b538SAndroid Build Coastguard Worker using ::testing::_;
38*6777b538SAndroid Build Coastguard Worker using ::testing::Assign;
39*6777b538SAndroid Build Coastguard Worker using ::testing::AtMost;
40*6777b538SAndroid Build Coastguard Worker using ::testing::DoAll;
41*6777b538SAndroid Build Coastguard Worker using ::testing::Exactly;
42*6777b538SAndroid Build Coastguard Worker using ::testing::IgnoreResult;
43*6777b538SAndroid Build Coastguard Worker using ::testing::Invoke;
44*6777b538SAndroid Build Coastguard Worker using ::testing::InvokeWithoutArgs;
45*6777b538SAndroid Build Coastguard Worker using ::testing::NiceMock;
46*6777b538SAndroid Build Coastguard Worker using ::testing::Return;
47*6777b538SAndroid Build Coastguard Worker using ::testing::SaveArg;
48*6777b538SAndroid Build Coastguard Worker using ::testing::StrictMock;
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker namespace net {
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker namespace {
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacket1[] = {
55*6777b538SAndroid Build Coastguard Worker // Header
56*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
57*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
58*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
59*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
60*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
61*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker // Answer 1
64*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
65*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
66*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
67*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // TTL (4 bytes) is 1 second;
68*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, 0x00, 0x08, // RDLENGTH is 8 bytes.
69*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker // Answer 2
72*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', 0xc0,
73*6777b538SAndroid Build Coastguard Worker 0x14, // Pointer to "._tcp.local"
74*6777b538SAndroid Build Coastguard Worker 0x00, 0x0c, // TYPE is PTR.
75*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
76*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
77*6777b538SAndroid Build Coastguard Worker 0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
78*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
79*6777b538SAndroid Build Coastguard Worker
80*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacket1WithCapitalization[] = {
81*6777b538SAndroid Build Coastguard Worker // Header
82*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
83*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
84*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
85*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
86*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
87*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker // Answer 1
90*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 'T', 'C', 'P', 0x05,
91*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
92*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
93*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // TTL (4 bytes) is 1 second;
94*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, 0x00, 0x08, // RDLENGTH is 8 bytes.
95*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker // Answer 2
98*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'P', 'r', 'i', 'n', 't', 'e', 'R', 0xc0,
99*6777b538SAndroid Build Coastguard Worker 0x14, // Pointer to "._tcp.local"
100*6777b538SAndroid Build Coastguard Worker 0x00, 0x0c, // TYPE is PTR.
101*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
102*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
103*6777b538SAndroid Build Coastguard Worker 0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
104*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker const uint8_t kCorruptedPacketBadQuestion[] = {
107*6777b538SAndroid Build Coastguard Worker // Header
108*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
109*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
110*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // One question
111*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
112*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
113*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
114*6777b538SAndroid Build Coastguard Worker
115*6777b538SAndroid Build Coastguard Worker // Question is corrupted and cannot be read.
116*6777b538SAndroid Build Coastguard Worker 0x99, 'h', 'e', 'l', 'l', 'o', 0x00, 0x00, 0x00, 0x00, 0x00,
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker // Answer 1
119*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
120*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
121*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
122*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
123*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x99, // RDLENGTH is impossible
124*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
125*6777b538SAndroid Build Coastguard Worker
126*6777b538SAndroid Build Coastguard Worker // Answer 2
127*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'p', 'r', // Useless trailing data.
128*6777b538SAndroid Build Coastguard Worker };
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker const uint8_t kCorruptedPacketUnsalvagable[] = {
131*6777b538SAndroid Build Coastguard Worker // Header
132*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
133*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
134*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
135*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
136*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
137*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker // Answer 1
140*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
141*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
142*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
143*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
144*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x99, // RDLENGTH is impossible
145*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker // Answer 2
148*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'p', 'r', // Useless trailing data.
149*6777b538SAndroid Build Coastguard Worker };
150*6777b538SAndroid Build Coastguard Worker
151*6777b538SAndroid Build Coastguard Worker const uint8_t kCorruptedPacketDoubleRecord[] = {
152*6777b538SAndroid Build Coastguard Worker // Header
153*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
154*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
155*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
156*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
157*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
158*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker // Answer 1
161*6777b538SAndroid Build Coastguard Worker 0x06, 'p', 'r', 'i', 'v', 'e', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
162*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TYPE is A.
163*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
164*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
165*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x04, // RDLENGTH is 4
166*6777b538SAndroid Build Coastguard Worker 0x05, 0x03, 0xc0, 0x0c,
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker // Answer 2 -- Same key
169*6777b538SAndroid Build Coastguard Worker 0x06, 'p', 'r', 'i', 'v', 'e', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
170*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TYPE is A.
171*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
172*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
173*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x04, // RDLENGTH is 4
174*6777b538SAndroid Build Coastguard Worker 0x02, 0x03, 0x04, 0x05,
175*6777b538SAndroid Build Coastguard Worker };
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker const uint8_t kCorruptedPacketSalvagable[] = {
178*6777b538SAndroid Build Coastguard Worker // Header
179*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
180*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
181*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
182*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
183*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
184*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
185*6777b538SAndroid Build Coastguard Worker
186*6777b538SAndroid Build Coastguard Worker // Answer 1
187*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
188*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
189*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
190*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
191*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
192*6777b538SAndroid Build Coastguard Worker 0x99, 'h', 'e', 'l', 'l', 'o', // Bad RDATA format.
193*6777b538SAndroid Build Coastguard Worker 0xc0, 0x0c,
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker // Answer 2
196*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', 0xc0,
197*6777b538SAndroid Build Coastguard Worker 0x14, // Pointer to "._tcp.local"
198*6777b538SAndroid Build Coastguard Worker 0x00, 0x0c, // TYPE is PTR.
199*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
200*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
201*6777b538SAndroid Build Coastguard Worker 0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
202*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
203*6777b538SAndroid Build Coastguard Worker
204*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacket2[] = {
205*6777b538SAndroid Build Coastguard Worker // Header
206*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
207*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
208*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
209*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
210*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
211*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
212*6777b538SAndroid Build Coastguard Worker
213*6777b538SAndroid Build Coastguard Worker // Answer 1
214*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
215*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
216*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
217*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
218*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
219*6777b538SAndroid Build Coastguard Worker 0x05, 'z', 'z', 'z', 'z', 'z', 0xc0, 0x0c,
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker // Answer 2
222*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', 0xc0,
223*6777b538SAndroid Build Coastguard Worker 0x14, // Pointer to "._tcp.local"
224*6777b538SAndroid Build Coastguard Worker 0x00, 0x0c, // TYPE is PTR.
225*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
226*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
227*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
228*6777b538SAndroid Build Coastguard Worker 0x05, 'z', 'z', 'z', 'z', 'z', 0xc0, 0x32};
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacket3[] = {
231*6777b538SAndroid Build Coastguard Worker // Header
232*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
233*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
234*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
235*6777b538SAndroid Build Coastguard Worker 0x00, 0x02, // 2 RRs (answers)
236*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
237*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
238*6777b538SAndroid Build Coastguard Worker
239*6777b538SAndroid Build Coastguard Worker // Answer 1
240*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', //
241*6777b538SAndroid Build Coastguard Worker 0x04, '_', 't', 'c', 'p', //
242*6777b538SAndroid Build Coastguard Worker 0x05, 'l', 'o', 'c', 'a', 'l', //
243*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x0c, // TYPE is PTR.
244*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
245*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // TTL (4 bytes) is 1 second;
246*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, //
247*6777b538SAndroid Build Coastguard Worker 0x00, 0x08, // RDLENGTH is 8 bytes.
248*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', //
249*6777b538SAndroid Build Coastguard Worker 0xc0, 0x0c, //
250*6777b538SAndroid Build Coastguard Worker
251*6777b538SAndroid Build Coastguard Worker // Answer 2
252*6777b538SAndroid Build Coastguard Worker 0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r', //
253*6777b538SAndroid Build Coastguard Worker 0xc0, 0x14, // Pointer to "._tcp.local"
254*6777b538SAndroid Build Coastguard Worker 0x00, 0x0c, // TYPE is PTR.
255*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
256*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // TTL (4 bytes) is 3 seconds.
257*6777b538SAndroid Build Coastguard Worker 0x00, 0x03, //
258*6777b538SAndroid Build Coastguard Worker 0x00, 0x08, // RDLENGTH is 8 bytes.
259*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', //
260*6777b538SAndroid Build Coastguard Worker 0xc0, 0x32};
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker const uint8_t kQueryPacketPrivet[] = {
263*6777b538SAndroid Build Coastguard Worker // Header
264*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
265*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No flags.
266*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // One question.
267*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 RRs (answers)
268*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
269*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker // Question
272*6777b538SAndroid Build Coastguard Worker // This part is echoed back from the respective query.
273*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
274*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
275*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
276*6777b538SAndroid Build Coastguard Worker };
277*6777b538SAndroid Build Coastguard Worker
278*6777b538SAndroid Build Coastguard Worker const uint8_t kQueryPacketPrivetWithCapitalization[] = {
279*6777b538SAndroid Build Coastguard Worker // Header
280*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
281*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No flags.
282*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // One question.
283*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 RRs (answers)
284*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
285*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
286*6777b538SAndroid Build Coastguard Worker
287*6777b538SAndroid Build Coastguard Worker // Question
288*6777b538SAndroid Build Coastguard Worker // This part is echoed back from the respective query.
289*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'P', 'R', 'I', 'V', 'E', 'T', 0x04, '_', 't', 'c', 'p', 0x05,
290*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
291*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
292*6777b538SAndroid Build Coastguard Worker };
293*6777b538SAndroid Build Coastguard Worker
294*6777b538SAndroid Build Coastguard Worker const uint8_t kQueryPacketPrivetA[] = {
295*6777b538SAndroid Build Coastguard Worker // Header
296*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
297*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No flags.
298*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // One question.
299*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 RRs (answers)
300*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
301*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
302*6777b538SAndroid Build Coastguard Worker
303*6777b538SAndroid Build Coastguard Worker // Question
304*6777b538SAndroid Build Coastguard Worker // This part is echoed back from the respective query.
305*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
306*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x01, // TYPE is A.
307*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
308*6777b538SAndroid Build Coastguard Worker };
309*6777b538SAndroid Build Coastguard Worker
310*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacketAdditionalOnly[] = {
311*6777b538SAndroid Build Coastguard Worker // Header
312*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
313*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
314*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
315*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 2 RRs (answers)
316*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
317*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // 0 additional RRs
318*6777b538SAndroid Build Coastguard Worker
319*6777b538SAndroid Build Coastguard Worker // Answer 1
320*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
321*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
322*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
323*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
324*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x08, // RDLENGTH is 8 bytes.
325*6777b538SAndroid Build Coastguard Worker 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
326*6777b538SAndroid Build Coastguard Worker };
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacketNsec[] = {
329*6777b538SAndroid Build Coastguard Worker // Header
330*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
331*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
332*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
333*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // 1 RR (answers)
334*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
335*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
336*6777b538SAndroid Build Coastguard Worker
337*6777b538SAndroid Build Coastguard Worker // Answer 1
338*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
339*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x2f, // TYPE is NSEC.
340*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
341*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 48 seconds.
342*6777b538SAndroid Build Coastguard Worker 0x24, 0x74, 0x00, 0x06, // RDLENGTH is 6 bytes.
343*6777b538SAndroid Build Coastguard Worker 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x08 // Only A record present
344*6777b538SAndroid Build Coastguard Worker };
345*6777b538SAndroid Build Coastguard Worker
346*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacketAPrivet[] = {
347*6777b538SAndroid Build Coastguard Worker // Header
348*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
349*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
350*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
351*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // 1 RR (answers)
352*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
353*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
354*6777b538SAndroid Build Coastguard Worker
355*6777b538SAndroid Build Coastguard Worker // Answer 1
356*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
357*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x01, // TYPE is A.
358*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
359*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // TTL (4 bytes) is 5 seconds
360*6777b538SAndroid Build Coastguard Worker 0x00, 0x05, 0x00, 0x04, // RDLENGTH is 4 bytes.
361*6777b538SAndroid Build Coastguard Worker 0xc0, 0x0c, 0x00, 0x02,
362*6777b538SAndroid Build Coastguard Worker };
363*6777b538SAndroid Build Coastguard Worker
364*6777b538SAndroid Build Coastguard Worker const uint8_t kSamplePacketGoodbye[] = {
365*6777b538SAndroid Build Coastguard Worker // Header
366*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // ID is zeroed out
367*6777b538SAndroid Build Coastguard Worker 0x81, 0x80, // Standard query response, RA, no error
368*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // No questions (for simplicity)
369*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // 2 RRs (answers)
370*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 authority RRs
371*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // 0 additional RRs
372*6777b538SAndroid Build Coastguard Worker
373*6777b538SAndroid Build Coastguard Worker // Answer 1
374*6777b538SAndroid Build Coastguard Worker 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 't', 'c', 'p', 0x05,
375*6777b538SAndroid Build Coastguard Worker 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
376*6777b538SAndroid Build Coastguard Worker 0x00, 0x01, // CLASS is IN.
377*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, // TTL (4 bytes) is zero;
378*6777b538SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x08, // RDLENGTH is 8 bytes.
379*6777b538SAndroid Build Coastguard Worker 0x05, 'z', 'z', 'z', 'z', 'z', 0xc0, 0x0c,
380*6777b538SAndroid Build Coastguard Worker };
381*6777b538SAndroid Build Coastguard Worker
MakeString(const uint8_t * data,unsigned size)382*6777b538SAndroid Build Coastguard Worker std::string MakeString(const uint8_t* data, unsigned size) {
383*6777b538SAndroid Build Coastguard Worker return std::string(reinterpret_cast<const char*>(data), size);
384*6777b538SAndroid Build Coastguard Worker }
385*6777b538SAndroid Build Coastguard Worker
386*6777b538SAndroid Build Coastguard Worker class PtrRecordCopyContainer {
387*6777b538SAndroid Build Coastguard Worker public:
388*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer() = default;
389*6777b538SAndroid Build Coastguard Worker ~PtrRecordCopyContainer() = default;
390*6777b538SAndroid Build Coastguard Worker
is_set() const391*6777b538SAndroid Build Coastguard Worker bool is_set() const { return set_; }
392*6777b538SAndroid Build Coastguard Worker
SaveWithDummyArg(int unused,const RecordParsed * value)393*6777b538SAndroid Build Coastguard Worker void SaveWithDummyArg(int unused, const RecordParsed* value) {
394*6777b538SAndroid Build Coastguard Worker Save(value);
395*6777b538SAndroid Build Coastguard Worker }
396*6777b538SAndroid Build Coastguard Worker
Save(const RecordParsed * value)397*6777b538SAndroid Build Coastguard Worker void Save(const RecordParsed* value) {
398*6777b538SAndroid Build Coastguard Worker set_ = true;
399*6777b538SAndroid Build Coastguard Worker name_ = value->name();
400*6777b538SAndroid Build Coastguard Worker ptrdomain_ = value->rdata<PtrRecordRdata>()->ptrdomain();
401*6777b538SAndroid Build Coastguard Worker ttl_ = value->ttl();
402*6777b538SAndroid Build Coastguard Worker }
403*6777b538SAndroid Build Coastguard Worker
IsRecordWith(const std::string & name,const std::string & ptrdomain)404*6777b538SAndroid Build Coastguard Worker bool IsRecordWith(const std::string& name, const std::string& ptrdomain) {
405*6777b538SAndroid Build Coastguard Worker return set_ && name_ == name && ptrdomain_ == ptrdomain;
406*6777b538SAndroid Build Coastguard Worker }
407*6777b538SAndroid Build Coastguard Worker
name()408*6777b538SAndroid Build Coastguard Worker const std::string& name() { return name_; }
ptrdomain()409*6777b538SAndroid Build Coastguard Worker const std::string& ptrdomain() { return ptrdomain_; }
ttl()410*6777b538SAndroid Build Coastguard Worker int ttl() { return ttl_; }
411*6777b538SAndroid Build Coastguard Worker
412*6777b538SAndroid Build Coastguard Worker private:
413*6777b538SAndroid Build Coastguard Worker bool set_;
414*6777b538SAndroid Build Coastguard Worker std::string name_;
415*6777b538SAndroid Build Coastguard Worker std::string ptrdomain_;
416*6777b538SAndroid Build Coastguard Worker int ttl_;
417*6777b538SAndroid Build Coastguard Worker };
418*6777b538SAndroid Build Coastguard Worker
419*6777b538SAndroid Build Coastguard Worker class MockClock : public base::Clock {
420*6777b538SAndroid Build Coastguard Worker public:
421*6777b538SAndroid Build Coastguard Worker MockClock() = default;
422*6777b538SAndroid Build Coastguard Worker
423*6777b538SAndroid Build Coastguard Worker MockClock(const MockClock&) = delete;
424*6777b538SAndroid Build Coastguard Worker MockClock& operator=(const MockClock&) = delete;
425*6777b538SAndroid Build Coastguard Worker
426*6777b538SAndroid Build Coastguard Worker ~MockClock() override = default;
427*6777b538SAndroid Build Coastguard Worker
428*6777b538SAndroid Build Coastguard Worker MOCK_CONST_METHOD0(Now, base::Time());
429*6777b538SAndroid Build Coastguard Worker };
430*6777b538SAndroid Build Coastguard Worker
431*6777b538SAndroid Build Coastguard Worker class MockTimer : public base::MockOneShotTimer {
432*6777b538SAndroid Build Coastguard Worker public:
433*6777b538SAndroid Build Coastguard Worker MockTimer() = default;
434*6777b538SAndroid Build Coastguard Worker
435*6777b538SAndroid Build Coastguard Worker MockTimer(const MockTimer&) = delete;
436*6777b538SAndroid Build Coastguard Worker MockTimer& operator=(const MockTimer&) = delete;
437*6777b538SAndroid Build Coastguard Worker
438*6777b538SAndroid Build Coastguard Worker ~MockTimer() override = default;
439*6777b538SAndroid Build Coastguard Worker
Start(const base::Location & posted_from,base::TimeDelta delay,base::OnceClosure user_task)440*6777b538SAndroid Build Coastguard Worker void Start(const base::Location& posted_from,
441*6777b538SAndroid Build Coastguard Worker base::TimeDelta delay,
442*6777b538SAndroid Build Coastguard Worker base::OnceClosure user_task) override {
443*6777b538SAndroid Build Coastguard Worker StartObserver(posted_from, delay);
444*6777b538SAndroid Build Coastguard Worker base::MockOneShotTimer::Start(posted_from, delay, std::move(user_task));
445*6777b538SAndroid Build Coastguard Worker }
446*6777b538SAndroid Build Coastguard Worker
447*6777b538SAndroid Build Coastguard Worker // StartObserver is invoked when MockTimer::Start() is called.
448*6777b538SAndroid Build Coastguard Worker // Does not replace the behavior of MockTimer::Start().
449*6777b538SAndroid Build Coastguard Worker MOCK_METHOD2(StartObserver,
450*6777b538SAndroid Build Coastguard Worker void(const base::Location& posted_from, base::TimeDelta delay));
451*6777b538SAndroid Build Coastguard Worker };
452*6777b538SAndroid Build Coastguard Worker
453*6777b538SAndroid Build Coastguard Worker } // namespace
454*6777b538SAndroid Build Coastguard Worker
455*6777b538SAndroid Build Coastguard Worker class MDnsTest : public TestWithTaskEnvironment {
456*6777b538SAndroid Build Coastguard Worker public:
457*6777b538SAndroid Build Coastguard Worker void SetUp() override;
458*6777b538SAndroid Build Coastguard Worker void DeleteTransaction();
459*6777b538SAndroid Build Coastguard Worker void DeleteBothListeners();
460*6777b538SAndroid Build Coastguard Worker void RunFor(base::TimeDelta time_period);
461*6777b538SAndroid Build Coastguard Worker void Stop();
462*6777b538SAndroid Build Coastguard Worker
463*6777b538SAndroid Build Coastguard Worker MOCK_METHOD2(MockableRecordCallback, void(MDnsTransaction::Result result,
464*6777b538SAndroid Build Coastguard Worker const RecordParsed* record));
465*6777b538SAndroid Build Coastguard Worker
466*6777b538SAndroid Build Coastguard Worker MOCK_METHOD2(MockableRecordCallback2, void(MDnsTransaction::Result result,
467*6777b538SAndroid Build Coastguard Worker const RecordParsed* record));
468*6777b538SAndroid Build Coastguard Worker
469*6777b538SAndroid Build Coastguard Worker protected:
470*6777b538SAndroid Build Coastguard Worker void ExpectPacket(const uint8_t* packet, unsigned size);
471*6777b538SAndroid Build Coastguard Worker void SimulatePacketReceive(const uint8_t* packet, unsigned size);
472*6777b538SAndroid Build Coastguard Worker
473*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::Clock> test_clock_; // Must outlive `test_client_`.
474*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsClientImpl> test_client_;
475*6777b538SAndroid Build Coastguard Worker IPEndPoint mdns_ipv4_endpoint_;
476*6777b538SAndroid Build Coastguard Worker StrictMock<MockMDnsSocketFactory> socket_factory_;
477*6777b538SAndroid Build Coastguard Worker
478*6777b538SAndroid Build Coastguard Worker // Transactions and listeners that can be deleted by class methods for
479*6777b538SAndroid Build Coastguard Worker // reentrancy tests.
480*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_;
481*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener1_;
482*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener2_;
483*6777b538SAndroid Build Coastguard Worker base::RunLoop loop_;
484*6777b538SAndroid Build Coastguard Worker };
485*6777b538SAndroid Build Coastguard Worker
486*6777b538SAndroid Build Coastguard Worker class MockListenerDelegate : public MDnsListener::Delegate {
487*6777b538SAndroid Build Coastguard Worker public:
488*6777b538SAndroid Build Coastguard Worker MOCK_METHOD2(OnRecordUpdate,
489*6777b538SAndroid Build Coastguard Worker void(MDnsListener::UpdateType update,
490*6777b538SAndroid Build Coastguard Worker const RecordParsed* records));
491*6777b538SAndroid Build Coastguard Worker MOCK_METHOD2(OnNsecRecord, void(const std::string&, unsigned));
492*6777b538SAndroid Build Coastguard Worker MOCK_METHOD0(OnCachePurged, void());
493*6777b538SAndroid Build Coastguard Worker };
494*6777b538SAndroid Build Coastguard Worker
SetUp()495*6777b538SAndroid Build Coastguard Worker void MDnsTest::SetUp() {
496*6777b538SAndroid Build Coastguard Worker test_client_ = std::make_unique<MDnsClientImpl>();
497*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(test_client_->StartListening(&socket_factory_), test::IsOk());
498*6777b538SAndroid Build Coastguard Worker }
499*6777b538SAndroid Build Coastguard Worker
SimulatePacketReceive(const uint8_t * packet,unsigned size)500*6777b538SAndroid Build Coastguard Worker void MDnsTest::SimulatePacketReceive(const uint8_t* packet, unsigned size) {
501*6777b538SAndroid Build Coastguard Worker socket_factory_.SimulateReceive(packet, size);
502*6777b538SAndroid Build Coastguard Worker }
503*6777b538SAndroid Build Coastguard Worker
ExpectPacket(const uint8_t * packet,unsigned size)504*6777b538SAndroid Build Coastguard Worker void MDnsTest::ExpectPacket(const uint8_t* packet, unsigned size) {
505*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(socket_factory_, OnSendTo(MakeString(packet, size)))
506*6777b538SAndroid Build Coastguard Worker .Times(2);
507*6777b538SAndroid Build Coastguard Worker }
508*6777b538SAndroid Build Coastguard Worker
DeleteTransaction()509*6777b538SAndroid Build Coastguard Worker void MDnsTest::DeleteTransaction() {
510*6777b538SAndroid Build Coastguard Worker transaction_.reset();
511*6777b538SAndroid Build Coastguard Worker }
512*6777b538SAndroid Build Coastguard Worker
DeleteBothListeners()513*6777b538SAndroid Build Coastguard Worker void MDnsTest::DeleteBothListeners() {
514*6777b538SAndroid Build Coastguard Worker listener1_.reset();
515*6777b538SAndroid Build Coastguard Worker listener2_.reset();
516*6777b538SAndroid Build Coastguard Worker }
517*6777b538SAndroid Build Coastguard Worker
RunFor(base::TimeDelta time_period)518*6777b538SAndroid Build Coastguard Worker void MDnsTest::RunFor(base::TimeDelta time_period) {
519*6777b538SAndroid Build Coastguard Worker base::CancelableOnceCallback<void()> callback(
520*6777b538SAndroid Build Coastguard Worker base::BindOnce(&MDnsTest::Stop, base::Unretained(this)));
521*6777b538SAndroid Build Coastguard Worker base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
522*6777b538SAndroid Build Coastguard Worker FROM_HERE, callback.callback(), time_period);
523*6777b538SAndroid Build Coastguard Worker
524*6777b538SAndroid Build Coastguard Worker loop_.Run();
525*6777b538SAndroid Build Coastguard Worker callback.Cancel();
526*6777b538SAndroid Build Coastguard Worker }
527*6777b538SAndroid Build Coastguard Worker
Stop()528*6777b538SAndroid Build Coastguard Worker void MDnsTest::Stop() {
529*6777b538SAndroid Build Coastguard Worker loop_.QuitWhenIdle();
530*6777b538SAndroid Build Coastguard Worker }
531*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,PassiveListeners)532*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, PassiveListeners) {
533*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
534*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_printer;
535*6777b538SAndroid Build Coastguard Worker
536*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
537*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_printer;
538*6777b538SAndroid Build Coastguard Worker
539*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
540*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
541*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
542*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
543*6777b538SAndroid Build Coastguard Worker
544*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
545*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_printer->Start());
546*6777b538SAndroid Build Coastguard Worker
547*6777b538SAndroid Build Coastguard Worker // Send the same packet twice to ensure no records are double-counted.
548*6777b538SAndroid Build Coastguard Worker
549*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
550*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
551*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(
552*6777b538SAndroid Build Coastguard Worker &record_privet,
553*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
554*6777b538SAndroid Build Coastguard Worker
555*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
556*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
557*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(
558*6777b538SAndroid Build Coastguard Worker &record_printer,
559*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
560*6777b538SAndroid Build Coastguard Worker
561*6777b538SAndroid Build Coastguard Worker
562*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
563*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
564*6777b538SAndroid Build Coastguard Worker
565*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._tcp.local",
566*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
567*6777b538SAndroid Build Coastguard Worker
568*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_printer.IsRecordWith("_printer._tcp.local",
569*6777b538SAndroid Build Coastguard Worker "hello._printer._tcp.local"));
570*6777b538SAndroid Build Coastguard Worker
571*6777b538SAndroid Build Coastguard Worker listener_privet.reset();
572*6777b538SAndroid Build Coastguard Worker listener_printer.reset();
573*6777b538SAndroid Build Coastguard Worker }
574*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,PassiveListenersWithCapitalization)575*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, PassiveListenersWithCapitalization) {
576*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
577*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_printer;
578*6777b538SAndroid Build Coastguard Worker
579*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
580*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_printer;
581*6777b538SAndroid Build Coastguard Worker
582*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
583*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.LOCAL", &delegate_privet);
584*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
585*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_prinTER._Tcp.Local", &delegate_printer);
586*6777b538SAndroid Build Coastguard Worker
587*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
588*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_printer->Start());
589*6777b538SAndroid Build Coastguard Worker
590*6777b538SAndroid Build Coastguard Worker // Send the same packet twice to ensure no records are double-counted.
591*6777b538SAndroid Build Coastguard Worker
592*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
593*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
594*6777b538SAndroid Build Coastguard Worker .WillOnce(
595*6777b538SAndroid Build Coastguard Worker Invoke(&record_privet, &PtrRecordCopyContainer::SaveWithDummyArg));
596*6777b538SAndroid Build Coastguard Worker
597*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
598*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
599*6777b538SAndroid Build Coastguard Worker .WillOnce(
600*6777b538SAndroid Build Coastguard Worker Invoke(&record_printer, &PtrRecordCopyContainer::SaveWithDummyArg));
601*6777b538SAndroid Build Coastguard Worker
602*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1WithCapitalization,
603*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacket1WithCapitalization));
604*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1WithCapitalization,
605*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacket1WithCapitalization));
606*6777b538SAndroid Build Coastguard Worker
607*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._TCP.local",
608*6777b538SAndroid Build Coastguard Worker "hello._privet._TCP.local"));
609*6777b538SAndroid Build Coastguard Worker
610*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_printer.IsRecordWith("_PrinteR._TCP.local",
611*6777b538SAndroid Build Coastguard Worker "hello._PrinteR._TCP.local"));
612*6777b538SAndroid Build Coastguard Worker
613*6777b538SAndroid Build Coastguard Worker listener_privet.reset();
614*6777b538SAndroid Build Coastguard Worker listener_printer.reset();
615*6777b538SAndroid Build Coastguard Worker }
616*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,PassiveListenersCacheCleanup)617*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, PassiveListenersCacheCleanup) {
618*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
619*6777b538SAndroid Build Coastguard Worker
620*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
621*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet2;
622*6777b538SAndroid Build Coastguard Worker
623*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
624*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
625*6777b538SAndroid Build Coastguard Worker
626*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
627*6777b538SAndroid Build Coastguard Worker
628*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
629*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
630*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(
631*6777b538SAndroid Build Coastguard Worker &record_privet,
632*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
633*6777b538SAndroid Build Coastguard Worker
634*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
635*6777b538SAndroid Build Coastguard Worker
636*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._tcp.local",
637*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
638*6777b538SAndroid Build Coastguard Worker
639*6777b538SAndroid Build Coastguard Worker // Expect record is removed when its TTL expires.
640*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
641*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
642*6777b538SAndroid Build Coastguard Worker .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::Stop),
643*6777b538SAndroid Build Coastguard Worker Invoke(&record_privet2,
644*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg)));
645*6777b538SAndroid Build Coastguard Worker
646*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(record_privet.ttl() + 1));
647*6777b538SAndroid Build Coastguard Worker
648*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet2.IsRecordWith("_privet._tcp.local",
649*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
650*6777b538SAndroid Build Coastguard Worker }
651*6777b538SAndroid Build Coastguard Worker
652*6777b538SAndroid Build Coastguard Worker // Ensure that the cleanup task scheduler won't schedule cleanup tasks in the
653*6777b538SAndroid Build Coastguard Worker // past if the system clock creeps past the expiration time while in the
654*6777b538SAndroid Build Coastguard Worker // cleanup dispatcher.
TEST_F(MDnsTest,CacheCleanupWithShortTTL)655*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, CacheCleanupWithShortTTL) {
656*6777b538SAndroid Build Coastguard Worker // Use a nonzero starting time as a base.
657*6777b538SAndroid Build Coastguard Worker base::Time start_time = base::Time() + base::Seconds(1);
658*6777b538SAndroid Build Coastguard Worker
659*6777b538SAndroid Build Coastguard Worker auto timer = std::make_unique<MockTimer>();
660*6777b538SAndroid Build Coastguard Worker MockTimer* timer_ptr = timer.get();
661*6777b538SAndroid Build Coastguard Worker
662*6777b538SAndroid Build Coastguard Worker auto owned_clock = std::make_unique<MockClock>();
663*6777b538SAndroid Build Coastguard Worker MockClock* clock = owned_clock.get();
664*6777b538SAndroid Build Coastguard Worker test_clock_ = std::move(owned_clock);
665*6777b538SAndroid Build Coastguard Worker test_client_ = std::make_unique<MDnsClientImpl>(clock, std::move(timer));
666*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(test_client_->StartListening(&socket_factory_), test::IsOk());
667*6777b538SAndroid Build Coastguard Worker
668*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*timer_ptr, StartObserver(_, _)).Times(1);
669*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*clock, Now())
670*6777b538SAndroid Build Coastguard Worker .Times(3)
671*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(start_time))
672*6777b538SAndroid Build Coastguard Worker .RetiresOnSaturation();
673*6777b538SAndroid Build Coastguard Worker
674*6777b538SAndroid Build Coastguard Worker // Receive two records with different TTL values.
675*6777b538SAndroid Build Coastguard Worker // TTL(privet)=1.0s
676*6777b538SAndroid Build Coastguard Worker // TTL(printer)=3.0s
677*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
678*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_printer;
679*6777b538SAndroid Build Coastguard Worker
680*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
681*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_printer;
682*6777b538SAndroid Build Coastguard Worker
683*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
684*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
685*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
686*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
687*6777b538SAndroid Build Coastguard Worker
688*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
689*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_printer->Start());
690*6777b538SAndroid Build Coastguard Worker
691*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
692*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
693*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
694*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
695*6777b538SAndroid Build Coastguard Worker
696*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket3, sizeof(kSamplePacket3));
697*6777b538SAndroid Build Coastguard Worker
698*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
699*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
700*6777b538SAndroid Build Coastguard Worker
701*6777b538SAndroid Build Coastguard Worker // Set the clock to 2.0s, which should clean up the 'privet' record, but not
702*6777b538SAndroid Build Coastguard Worker // the printer. The mock clock will change Now() mid-execution from 2s to 4s.
703*6777b538SAndroid Build Coastguard Worker // Note: expectations are FILO-ordered -- t+2 seconds is returned, then t+4.
704*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*clock, Now())
705*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(start_time + base::Seconds(4)))
706*6777b538SAndroid Build Coastguard Worker .RetiresOnSaturation();
707*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*clock, Now())
708*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(start_time + base::Seconds(2)))
709*6777b538SAndroid Build Coastguard Worker .RetiresOnSaturation();
710*6777b538SAndroid Build Coastguard Worker
711*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*timer_ptr, StartObserver(_, base::TimeDelta()));
712*6777b538SAndroid Build Coastguard Worker
713*6777b538SAndroid Build Coastguard Worker timer_ptr->Fire();
714*6777b538SAndroid Build Coastguard Worker }
715*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,StopListening)716*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, StopListening) {
717*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(test_client_->IsListening());
718*6777b538SAndroid Build Coastguard Worker
719*6777b538SAndroid Build Coastguard Worker test_client_->StopListening();
720*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(test_client_->IsListening());
721*6777b538SAndroid Build Coastguard Worker }
722*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,StopListening_CacheCleanupScheduled)723*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, StopListening_CacheCleanupScheduled) {
724*6777b538SAndroid Build Coastguard Worker auto owned_clock = std::make_unique<base::SimpleTestClock>();
725*6777b538SAndroid Build Coastguard Worker base::SimpleTestClock* clock = owned_clock.get();
726*6777b538SAndroid Build Coastguard Worker test_clock_ = std::move(owned_clock);
727*6777b538SAndroid Build Coastguard Worker
728*6777b538SAndroid Build Coastguard Worker // Use a nonzero starting time as a base.
729*6777b538SAndroid Build Coastguard Worker clock->SetNow(base::Time() + base::Seconds(1));
730*6777b538SAndroid Build Coastguard Worker auto cleanup_timer = std::make_unique<base::MockOneShotTimer>();
731*6777b538SAndroid Build Coastguard Worker base::OneShotTimer* cleanup_timer_ptr = cleanup_timer.get();
732*6777b538SAndroid Build Coastguard Worker
733*6777b538SAndroid Build Coastguard Worker test_client_ =
734*6777b538SAndroid Build Coastguard Worker std::make_unique<MDnsClientImpl>(clock, std::move(cleanup_timer));
735*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(test_client_->StartListening(&socket_factory_), test::IsOk());
736*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(test_client_->IsListening());
737*6777b538SAndroid Build Coastguard Worker
738*6777b538SAndroid Build Coastguard Worker // Receive one record (privet) with TTL=1s to schedule cleanup.
739*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket3, sizeof(kSamplePacket3));
740*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(cleanup_timer_ptr->IsRunning());
741*6777b538SAndroid Build Coastguard Worker
742*6777b538SAndroid Build Coastguard Worker test_client_->StopListening();
743*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(test_client_->IsListening());
744*6777b538SAndroid Build Coastguard Worker
745*6777b538SAndroid Build Coastguard Worker // Expect cleanup unscheduled.
746*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cleanup_timer_ptr->IsRunning());
747*6777b538SAndroid Build Coastguard Worker }
748*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,MalformedPacket)749*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, MalformedPacket) {
750*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_printer;
751*6777b538SAndroid Build Coastguard Worker
752*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_printer;
753*6777b538SAndroid Build Coastguard Worker
754*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
755*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
756*6777b538SAndroid Build Coastguard Worker
757*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_printer->Start());
758*6777b538SAndroid Build Coastguard Worker
759*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
760*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
761*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(
762*6777b538SAndroid Build Coastguard Worker &record_printer,
763*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
764*6777b538SAndroid Build Coastguard Worker
765*6777b538SAndroid Build Coastguard Worker // First, send unsalvagable packet to ensure we can deal with it.
766*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kCorruptedPacketUnsalvagable,
767*6777b538SAndroid Build Coastguard Worker sizeof(kCorruptedPacketUnsalvagable));
768*6777b538SAndroid Build Coastguard Worker
769*6777b538SAndroid Build Coastguard Worker // Regression test: send a packet where the question cannot be read.
770*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kCorruptedPacketBadQuestion,
771*6777b538SAndroid Build Coastguard Worker sizeof(kCorruptedPacketBadQuestion));
772*6777b538SAndroid Build Coastguard Worker
773*6777b538SAndroid Build Coastguard Worker // Then send salvagable packet to ensure we can extract useful records.
774*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kCorruptedPacketSalvagable,
775*6777b538SAndroid Build Coastguard Worker sizeof(kCorruptedPacketSalvagable));
776*6777b538SAndroid Build Coastguard Worker
777*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_printer.IsRecordWith("_printer._tcp.local",
778*6777b538SAndroid Build Coastguard Worker "hello._printer._tcp.local"));
779*6777b538SAndroid Build Coastguard Worker }
780*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionWithEmptyCache)781*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionWithEmptyCache) {
782*6777b538SAndroid Build Coastguard Worker ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
783*6777b538SAndroid Build Coastguard Worker
784*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
785*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
786*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
787*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
788*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
789*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
790*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
791*6777b538SAndroid Build Coastguard Worker
792*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
793*6777b538SAndroid Build Coastguard Worker
794*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
795*6777b538SAndroid Build Coastguard Worker
796*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _))
797*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
798*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(&record_privet,
799*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
800*6777b538SAndroid Build Coastguard Worker
801*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
802*6777b538SAndroid Build Coastguard Worker
803*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._tcp.local",
804*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
805*6777b538SAndroid Build Coastguard Worker }
806*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionWithEmptyCacheAndCapitalization)807*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionWithEmptyCacheAndCapitalization) {
808*6777b538SAndroid Build Coastguard Worker ExpectPacket(kQueryPacketPrivetWithCapitalization,
809*6777b538SAndroid Build Coastguard Worker sizeof(kQueryPacketPrivetWithCapitalization));
810*6777b538SAndroid Build Coastguard Worker
811*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
812*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
813*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_PRIVET._tcp.local",
814*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
815*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
816*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
817*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
818*6777b538SAndroid Build Coastguard Worker
819*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
820*6777b538SAndroid Build Coastguard Worker
821*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _))
824*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
825*6777b538SAndroid Build Coastguard Worker .WillOnce(
826*6777b538SAndroid Build Coastguard Worker Invoke(&record_privet, &PtrRecordCopyContainer::SaveWithDummyArg));
827*6777b538SAndroid Build Coastguard Worker
828*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1WithCapitalization,
829*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacket1WithCapitalization));
830*6777b538SAndroid Build Coastguard Worker
831*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._TCP.local",
832*6777b538SAndroid Build Coastguard Worker "hello._privet._TCP.local"));
833*6777b538SAndroid Build Coastguard Worker }
834*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionCacheOnlyNoResult)835*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionCacheOnlyNoResult) {
836*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
837*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
838*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
839*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_CACHE | MDnsTransaction::SINGLE_RESULT,
840*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
841*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
842*6777b538SAndroid Build Coastguard Worker
843*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this,
844*6777b538SAndroid Build Coastguard Worker MockableRecordCallback(MDnsTransaction::RESULT_NO_RESULTS, _))
845*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
846*6777b538SAndroid Build Coastguard Worker
847*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
848*6777b538SAndroid Build Coastguard Worker }
849*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionWithCache)850*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionWithCache) {
851*6777b538SAndroid Build Coastguard Worker // Listener to force the client to listen
852*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_irrelevant;
853*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_irrelevant =
854*6777b538SAndroid Build Coastguard Worker test_client_->CreateListener(dns_protocol::kTypeA,
855*6777b538SAndroid Build Coastguard Worker "codereview.chromium.local",
856*6777b538SAndroid Build Coastguard Worker &delegate_irrelevant);
857*6777b538SAndroid Build Coastguard Worker
858*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_irrelevant->Start());
859*6777b538SAndroid Build Coastguard Worker
860*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
861*6777b538SAndroid Build Coastguard Worker
862*6777b538SAndroid Build Coastguard Worker
863*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
864*6777b538SAndroid Build Coastguard Worker
865*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _))
866*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(&record_privet,
867*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
868*6777b538SAndroid Build Coastguard Worker
869*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
870*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
871*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
872*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
873*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
874*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
875*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
876*6777b538SAndroid Build Coastguard Worker
877*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
878*6777b538SAndroid Build Coastguard Worker
879*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._tcp.local",
880*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
881*6777b538SAndroid Build Coastguard Worker }
882*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,AdditionalRecords)883*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, AdditionalRecords) {
884*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
885*6777b538SAndroid Build Coastguard Worker
886*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
887*6777b538SAndroid Build Coastguard Worker
888*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
889*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
890*6777b538SAndroid Build Coastguard Worker
891*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
892*6777b538SAndroid Build Coastguard Worker
893*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
894*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
895*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(
896*6777b538SAndroid Build Coastguard Worker &record_privet,
897*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
898*6777b538SAndroid Build Coastguard Worker
899*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketAdditionalOnly,
900*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketAdditionalOnly));
901*6777b538SAndroid Build Coastguard Worker
902*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._tcp.local",
903*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
904*6777b538SAndroid Build Coastguard Worker }
905*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionTimeout)906*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionTimeout) {
907*6777b538SAndroid Build Coastguard Worker ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
908*6777b538SAndroid Build Coastguard Worker
909*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
910*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
911*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
912*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
913*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
914*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
915*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
916*6777b538SAndroid Build Coastguard Worker
917*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
918*6777b538SAndroid Build Coastguard Worker
919*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_NO_RESULTS,
920*6777b538SAndroid Build Coastguard Worker nullptr))
921*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
922*6777b538SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop));
923*6777b538SAndroid Build Coastguard Worker
924*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(4));
925*6777b538SAndroid Build Coastguard Worker }
926*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionMultipleRecords)927*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionMultipleRecords) {
928*6777b538SAndroid Build Coastguard Worker ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
929*6777b538SAndroid Build Coastguard Worker
930*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
931*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
932*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
933*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE,
934*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
935*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
936*6777b538SAndroid Build Coastguard Worker
937*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
938*6777b538SAndroid Build Coastguard Worker
939*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
940*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet2;
941*6777b538SAndroid Build Coastguard Worker
942*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _))
943*6777b538SAndroid Build Coastguard Worker .Times(Exactly(2))
944*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(&record_privet,
945*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg))
946*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(&record_privet2,
947*6777b538SAndroid Build Coastguard Worker &PtrRecordCopyContainer::SaveWithDummyArg));
948*6777b538SAndroid Build Coastguard Worker
949*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
950*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket2, sizeof(kSamplePacket2));
951*6777b538SAndroid Build Coastguard Worker
952*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet.IsRecordWith("_privet._tcp.local",
953*6777b538SAndroid Build Coastguard Worker "hello._privet._tcp.local"));
954*6777b538SAndroid Build Coastguard Worker
955*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(record_privet2.IsRecordWith("_privet._tcp.local",
956*6777b538SAndroid Build Coastguard Worker "zzzzz._privet._tcp.local"));
957*6777b538SAndroid Build Coastguard Worker
958*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this,
959*6777b538SAndroid Build Coastguard Worker MockableRecordCallback(MDnsTransaction::RESULT_DONE, nullptr))
960*6777b538SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs(this, &MDnsTest::Stop));
961*6777b538SAndroid Build Coastguard Worker
962*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(4));
963*6777b538SAndroid Build Coastguard Worker }
964*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionReentrantDelete)965*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionReentrantDelete) {
966*6777b538SAndroid Build Coastguard Worker ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
967*6777b538SAndroid Build Coastguard Worker
968*6777b538SAndroid Build Coastguard Worker transaction_ = test_client_->CreateTransaction(
969*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
970*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
971*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
972*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
973*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
974*6777b538SAndroid Build Coastguard Worker
975*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_->Start());
976*6777b538SAndroid Build Coastguard Worker
977*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_NO_RESULTS,
978*6777b538SAndroid Build Coastguard Worker nullptr))
979*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
980*6777b538SAndroid Build Coastguard Worker .WillOnce(DoAll(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction),
981*6777b538SAndroid Build Coastguard Worker InvokeWithoutArgs(this, &MDnsTest::Stop)));
982*6777b538SAndroid Build Coastguard Worker
983*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(4));
984*6777b538SAndroid Build Coastguard Worker
985*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, transaction_.get());
986*6777b538SAndroid Build Coastguard Worker }
987*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionReentrantDeleteFromCache)988*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionReentrantDeleteFromCache) {
989*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_irrelevant;
990*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_irrelevant =
991*6777b538SAndroid Build Coastguard Worker test_client_->CreateListener(dns_protocol::kTypeA,
992*6777b538SAndroid Build Coastguard Worker "codereview.chromium.local",
993*6777b538SAndroid Build Coastguard Worker &delegate_irrelevant);
994*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_irrelevant->Start());
995*6777b538SAndroid Build Coastguard Worker
996*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
997*6777b538SAndroid Build Coastguard Worker
998*6777b538SAndroid Build Coastguard Worker transaction_ = test_client_->CreateTransaction(
999*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
1000*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE,
1001*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
1002*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
1003*6777b538SAndroid Build Coastguard Worker
1004*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _))
1005*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
1006*6777b538SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs(this, &MDnsTest::DeleteTransaction));
1007*6777b538SAndroid Build Coastguard Worker
1008*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_->Start());
1009*6777b538SAndroid Build Coastguard Worker
1010*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, transaction_.get());
1011*6777b538SAndroid Build Coastguard Worker }
1012*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,TransactionReentrantCacheLookupStart)1013*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, TransactionReentrantCacheLookupStart) {
1014*6777b538SAndroid Build Coastguard Worker ExpectPacket(kQueryPacketPrivet, sizeof(kQueryPacketPrivet));
1015*6777b538SAndroid Build Coastguard Worker
1016*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction1 =
1017*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
1018*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
1019*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
1020*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
1021*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
1022*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
1023*6777b538SAndroid Build Coastguard Worker
1024*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction2 =
1025*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
1026*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_printer._tcp.local",
1027*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_CACHE | MDnsTransaction::SINGLE_RESULT,
1028*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback2,
1029*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
1030*6777b538SAndroid Build Coastguard Worker
1031*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback2(MDnsTransaction::RESULT_RECORD,
1032*6777b538SAndroid Build Coastguard Worker _))
1033*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
1034*6777b538SAndroid Build Coastguard Worker
1035*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD,
1036*6777b538SAndroid Build Coastguard Worker _))
1037*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
1038*6777b538SAndroid Build Coastguard Worker .WillOnce(IgnoreResult(InvokeWithoutArgs(transaction2.get(),
1039*6777b538SAndroid Build Coastguard Worker &MDnsTransaction::Start)));
1040*6777b538SAndroid Build Coastguard Worker
1041*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction1->Start());
1042*6777b538SAndroid Build Coastguard Worker
1043*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
1044*6777b538SAndroid Build Coastguard Worker }
1045*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,GoodbyePacketNotification)1046*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, GoodbyePacketNotification) {
1047*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1048*6777b538SAndroid Build Coastguard Worker
1049*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1050*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
1051*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1052*6777b538SAndroid Build Coastguard Worker
1053*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketGoodbye, sizeof(kSamplePacketGoodbye));
1054*6777b538SAndroid Build Coastguard Worker
1055*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(2));
1056*6777b538SAndroid Build Coastguard Worker }
1057*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,GoodbyePacketRemoval)1058*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, GoodbyePacketRemoval) {
1059*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1060*6777b538SAndroid Build Coastguard Worker
1061*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1062*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
1063*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1064*6777b538SAndroid Build Coastguard Worker
1065*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
1066*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
1067*6777b538SAndroid Build Coastguard Worker
1068*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket2, sizeof(kSamplePacket2));
1069*6777b538SAndroid Build Coastguard Worker
1070*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketGoodbye, sizeof(kSamplePacketGoodbye));
1071*6777b538SAndroid Build Coastguard Worker
1072*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
1073*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1));
1074*6777b538SAndroid Build Coastguard Worker
1075*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(2));
1076*6777b538SAndroid Build Coastguard Worker }
1077*6777b538SAndroid Build Coastguard Worker
1078*6777b538SAndroid Build Coastguard Worker // In order to reliably test reentrant listener deletes, we create two listeners
1079*6777b538SAndroid Build Coastguard Worker // and have each of them delete both, so we're guaranteed to try and deliver a
1080*6777b538SAndroid Build Coastguard Worker // callback to at least one deleted listener.
1081*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,ListenerReentrantDelete)1082*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, ListenerReentrantDelete) {
1083*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1084*6777b538SAndroid Build Coastguard Worker
1085*6777b538SAndroid Build Coastguard Worker listener1_ = test_client_->CreateListener(
1086*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
1087*6777b538SAndroid Build Coastguard Worker
1088*6777b538SAndroid Build Coastguard Worker listener2_ = test_client_->CreateListener(
1089*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
1090*6777b538SAndroid Build Coastguard Worker
1091*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener1_->Start());
1092*6777b538SAndroid Build Coastguard Worker
1093*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener2_->Start());
1094*6777b538SAndroid Build Coastguard Worker
1095*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
1096*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
1097*6777b538SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs(this, &MDnsTest::DeleteBothListeners));
1098*6777b538SAndroid Build Coastguard Worker
1099*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
1100*6777b538SAndroid Build Coastguard Worker
1101*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, listener1_.get());
1102*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, listener2_.get());
1103*6777b538SAndroid Build Coastguard Worker }
1104*6777b538SAndroid Build Coastguard Worker
ACTION_P(SaveIPAddress,ip_container)1105*6777b538SAndroid Build Coastguard Worker ACTION_P(SaveIPAddress, ip_container) {
1106*6777b538SAndroid Build Coastguard Worker ::testing::StaticAssertTypeEq<const RecordParsed*, arg1_type>();
1107*6777b538SAndroid Build Coastguard Worker ::testing::StaticAssertTypeEq<IPAddress*, ip_container_type>();
1108*6777b538SAndroid Build Coastguard Worker
1109*6777b538SAndroid Build Coastguard Worker *ip_container = arg1->template rdata<ARecordRdata>()->address();
1110*6777b538SAndroid Build Coastguard Worker }
1111*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,DoubleRecordDisagreeing)1112*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, DoubleRecordDisagreeing) {
1113*6777b538SAndroid Build Coastguard Worker IPAddress address;
1114*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1115*6777b538SAndroid Build Coastguard Worker
1116*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1117*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypeA, "privet.local", &delegate_privet);
1118*6777b538SAndroid Build Coastguard Worker
1119*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1120*6777b538SAndroid Build Coastguard Worker
1121*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
1122*6777b538SAndroid Build Coastguard Worker .Times(Exactly(1))
1123*6777b538SAndroid Build Coastguard Worker .WillOnce(SaveIPAddress(&address));
1124*6777b538SAndroid Build Coastguard Worker
1125*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kCorruptedPacketDoubleRecord,
1126*6777b538SAndroid Build Coastguard Worker sizeof(kCorruptedPacketDoubleRecord));
1127*6777b538SAndroid Build Coastguard Worker
1128*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("2.3.4.5", address.ToString());
1129*6777b538SAndroid Build Coastguard Worker }
1130*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,NsecWithListener)1131*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, NsecWithListener) {
1132*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1133*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1134*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypeA, "_privet._tcp.local", &delegate_privet);
1135*6777b538SAndroid Build Coastguard Worker
1136*6777b538SAndroid Build Coastguard Worker // Test to make sure nsec callback is NOT called for PTR
1137*6777b538SAndroid Build Coastguard Worker // (which is marked as existing).
1138*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet2;
1139*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet2 = test_client_->CreateListener(
1140*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet2);
1141*6777b538SAndroid Build Coastguard Worker
1142*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1143*6777b538SAndroid Build Coastguard Worker
1144*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet,
1145*6777b538SAndroid Build Coastguard Worker OnNsecRecord("_privet._tcp.local", dns_protocol::kTypeA));
1146*6777b538SAndroid Build Coastguard Worker
1147*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketNsec,
1148*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketNsec));
1149*6777b538SAndroid Build Coastguard Worker }
1150*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,NsecWithTransactionFromNetwork)1151*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, NsecWithTransactionFromNetwork) {
1152*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet =
1153*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
1154*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypeA, "_privet._tcp.local",
1155*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
1156*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
1157*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
1158*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
1159*6777b538SAndroid Build Coastguard Worker
1160*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(socket_factory_, OnSendTo(_)).Times(2);
1161*6777b538SAndroid Build Coastguard Worker
1162*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet->Start());
1163*6777b538SAndroid Build Coastguard Worker
1164*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this,
1165*6777b538SAndroid Build Coastguard Worker MockableRecordCallback(MDnsTransaction::RESULT_NSEC, nullptr));
1166*6777b538SAndroid Build Coastguard Worker
1167*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketNsec,
1168*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketNsec));
1169*6777b538SAndroid Build Coastguard Worker }
1170*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,NsecWithTransactionFromCache)1171*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, NsecWithTransactionFromCache) {
1172*6777b538SAndroid Build Coastguard Worker // Force mDNS to listen.
1173*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_irrelevant;
1174*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_irrelevant =
1175*6777b538SAndroid Build Coastguard Worker test_client_->CreateListener(dns_protocol::kTypePTR, "_privet._tcp.local",
1176*6777b538SAndroid Build Coastguard Worker &delegate_irrelevant);
1177*6777b538SAndroid Build Coastguard Worker listener_irrelevant->Start();
1178*6777b538SAndroid Build Coastguard Worker
1179*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketNsec,
1180*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketNsec));
1181*6777b538SAndroid Build Coastguard Worker
1182*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*this,
1183*6777b538SAndroid Build Coastguard Worker MockableRecordCallback(MDnsTransaction::RESULT_NSEC, nullptr));
1184*6777b538SAndroid Build Coastguard Worker
1185*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet_a =
1186*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
1187*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypeA, "_privet._tcp.local",
1188*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
1189*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
1190*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
1191*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
1192*6777b538SAndroid Build Coastguard Worker
1193*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet_a->Start());
1194*6777b538SAndroid Build Coastguard Worker
1195*6777b538SAndroid Build Coastguard Worker // Test that a PTR transaction does NOT consider the same NSEC record to be a
1196*6777b538SAndroid Build Coastguard Worker // valid answer to the query
1197*6777b538SAndroid Build Coastguard Worker
1198*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsTransaction> transaction_privet_ptr =
1199*6777b538SAndroid Build Coastguard Worker test_client_->CreateTransaction(
1200*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local",
1201*6777b538SAndroid Build Coastguard Worker MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
1202*6777b538SAndroid Build Coastguard Worker MDnsTransaction::SINGLE_RESULT,
1203*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&MDnsTest::MockableRecordCallback,
1204*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
1205*6777b538SAndroid Build Coastguard Worker
1206*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(socket_factory_, OnSendTo(_)).Times(2);
1207*6777b538SAndroid Build Coastguard Worker
1208*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(transaction_privet_ptr->Start());
1209*6777b538SAndroid Build Coastguard Worker }
1210*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,NsecConflictRemoval)1211*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, NsecConflictRemoval) {
1212*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1213*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1214*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypeA, "_privet._tcp.local", &delegate_privet);
1215*6777b538SAndroid Build Coastguard Worker
1216*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1217*6777b538SAndroid Build Coastguard Worker
1218*6777b538SAndroid Build Coastguard Worker const RecordParsed* record1;
1219*6777b538SAndroid Build Coastguard Worker const RecordParsed* record2;
1220*6777b538SAndroid Build Coastguard Worker
1221*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
1222*6777b538SAndroid Build Coastguard Worker .WillOnce(SaveArg<1>(&record1));
1223*6777b538SAndroid Build Coastguard Worker
1224*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketAPrivet,
1225*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketAPrivet));
1226*6777b538SAndroid Build Coastguard Worker
1227*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
1228*6777b538SAndroid Build Coastguard Worker .WillOnce(SaveArg<1>(&record2));
1229*6777b538SAndroid Build Coastguard Worker
1230*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet,
1231*6777b538SAndroid Build Coastguard Worker OnNsecRecord("_privet._tcp.local", dns_protocol::kTypeA));
1232*6777b538SAndroid Build Coastguard Worker
1233*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketNsec,
1234*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketNsec));
1235*6777b538SAndroid Build Coastguard Worker
1236*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(record1, record2);
1237*6777b538SAndroid Build Coastguard Worker }
1238*6777b538SAndroid Build Coastguard Worker
1239*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1274091): Flaky on fuchsia.
1240*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
1241*6777b538SAndroid Build Coastguard Worker #define MAYBE_RefreshQuery DISABLED_RefreshQuery
1242*6777b538SAndroid Build Coastguard Worker #else
1243*6777b538SAndroid Build Coastguard Worker #define MAYBE_RefreshQuery RefreshQuery
1244*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(MDnsTest,MAYBE_RefreshQuery)1245*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, MAYBE_RefreshQuery) {
1246*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1247*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1248*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypeA, "_privet._tcp.local", &delegate_privet);
1249*6777b538SAndroid Build Coastguard Worker
1250*6777b538SAndroid Build Coastguard Worker listener_privet->SetActiveRefresh(true);
1251*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1252*6777b538SAndroid Build Coastguard Worker
1253*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _));
1254*6777b538SAndroid Build Coastguard Worker
1255*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacketAPrivet,
1256*6777b538SAndroid Build Coastguard Worker sizeof(kSamplePacketAPrivet));
1257*6777b538SAndroid Build Coastguard Worker
1258*6777b538SAndroid Build Coastguard Worker // Expecting 2 calls (one for ipv4 and one for ipv6) for each of the 2
1259*6777b538SAndroid Build Coastguard Worker // scheduled refresh queries.
1260*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(socket_factory_, OnSendTo(
1261*6777b538SAndroid Build Coastguard Worker MakeString(kQueryPacketPrivetA, sizeof(kQueryPacketPrivetA))))
1262*6777b538SAndroid Build Coastguard Worker .Times(4);
1263*6777b538SAndroid Build Coastguard Worker
1264*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _));
1265*6777b538SAndroid Build Coastguard Worker
1266*6777b538SAndroid Build Coastguard Worker RunFor(base::Seconds(6));
1267*6777b538SAndroid Build Coastguard Worker }
1268*6777b538SAndroid Build Coastguard Worker
1269*6777b538SAndroid Build Coastguard Worker // MDnsSocketFactory implementation that creates a single socket that will
1270*6777b538SAndroid Build Coastguard Worker // always fail on RecvFrom. Passing this to MdnsClient is expected to result in
1271*6777b538SAndroid Build Coastguard Worker // the client failing to start listening.
1272*6777b538SAndroid Build Coastguard Worker class FailingSocketFactory : public MDnsSocketFactory {
CreateSockets(std::vector<std::unique_ptr<DatagramServerSocket>> * sockets)1273*6777b538SAndroid Build Coastguard Worker void CreateSockets(
1274*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<DatagramServerSocket>>* sockets) override {
1275*6777b538SAndroid Build Coastguard Worker auto socket =
1276*6777b538SAndroid Build Coastguard Worker std::make_unique<MockMDnsDatagramServerSocket>(ADDRESS_FAMILY_IPV4);
1277*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket, RecvFrom(_, _, _, _))
1278*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(ERR_FAILED));
1279*6777b538SAndroid Build Coastguard Worker sockets->push_back(std::move(socket));
1280*6777b538SAndroid Build Coastguard Worker }
1281*6777b538SAndroid Build Coastguard Worker };
1282*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsTest,StartListeningFailure)1283*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, StartListeningFailure) {
1284*6777b538SAndroid Build Coastguard Worker test_client_ = std::make_unique<MDnsClientImpl>();
1285*6777b538SAndroid Build Coastguard Worker FailingSocketFactory socket_factory;
1286*6777b538SAndroid Build Coastguard Worker
1287*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(test_client_->StartListening(&socket_factory),
1288*6777b538SAndroid Build Coastguard Worker test::IsError(ERR_FAILED));
1289*6777b538SAndroid Build Coastguard Worker }
1290*6777b538SAndroid Build Coastguard Worker
1291*6777b538SAndroid Build Coastguard Worker // Test that the cache is cleared when it gets filled to unreasonable sizes.
TEST_F(MDnsTest,ClearOverfilledCache)1292*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsTest, ClearOverfilledCache) {
1293*6777b538SAndroid Build Coastguard Worker test_client_->core()->cache_for_testing()->set_entry_limit_for_testing(1);
1294*6777b538SAndroid Build Coastguard Worker
1295*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_privet;
1296*6777b538SAndroid Build Coastguard Worker StrictMock<MockListenerDelegate> delegate_printer;
1297*6777b538SAndroid Build Coastguard Worker
1298*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_privet;
1299*6777b538SAndroid Build Coastguard Worker PtrRecordCopyContainer record_printer;
1300*6777b538SAndroid Build Coastguard Worker
1301*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
1302*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_privet._tcp.local", &delegate_privet);
1303*6777b538SAndroid Build Coastguard Worker std::unique_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
1304*6777b538SAndroid Build Coastguard Worker dns_protocol::kTypePTR, "_printer._tcp.local", &delegate_printer);
1305*6777b538SAndroid Build Coastguard Worker
1306*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_privet->Start());
1307*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(listener_printer->Start());
1308*6777b538SAndroid Build Coastguard Worker
1309*6777b538SAndroid Build Coastguard Worker bool privet_added = false;
1310*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
1311*6777b538SAndroid Build Coastguard Worker .Times(AtMost(1))
1312*6777b538SAndroid Build Coastguard Worker .WillOnce(Assign(&privet_added, true));
1313*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
1314*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Assign(&privet_added, false));
1315*6777b538SAndroid Build Coastguard Worker
1316*6777b538SAndroid Build Coastguard Worker bool printer_added = false;
1317*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
1318*6777b538SAndroid Build Coastguard Worker .Times(AtMost(1))
1319*6777b538SAndroid Build Coastguard Worker .WillOnce(Assign(&printer_added, true));
1320*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_REMOVED, _))
1321*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Assign(&printer_added, false));
1322*6777b538SAndroid Build Coastguard Worker
1323*6777b538SAndroid Build Coastguard Worker // Fill past capacity and expect everything to eventually be removed.
1324*6777b538SAndroid Build Coastguard Worker SimulatePacketReceive(kSamplePacket1, sizeof(kSamplePacket1));
1325*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1326*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(privet_added);
1327*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(printer_added);
1328*6777b538SAndroid Build Coastguard Worker }
1329*6777b538SAndroid Build Coastguard Worker
1330*6777b538SAndroid Build Coastguard Worker // Note: These tests assume that the ipv4 socket will always be created first.
1331*6777b538SAndroid Build Coastguard Worker // This is a simplifying assumption based on the way the code works now.
1332*6777b538SAndroid Build Coastguard Worker class SimpleMockSocketFactory : public MDnsSocketFactory {
1333*6777b538SAndroid Build Coastguard Worker public:
CreateSockets(std::vector<std::unique_ptr<DatagramServerSocket>> * sockets)1334*6777b538SAndroid Build Coastguard Worker void CreateSockets(
1335*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<DatagramServerSocket>>* sockets) override {
1336*6777b538SAndroid Build Coastguard Worker sockets->clear();
1337*6777b538SAndroid Build Coastguard Worker sockets->swap(sockets_);
1338*6777b538SAndroid Build Coastguard Worker }
1339*6777b538SAndroid Build Coastguard Worker
PushSocket(std::unique_ptr<DatagramServerSocket> socket)1340*6777b538SAndroid Build Coastguard Worker void PushSocket(std::unique_ptr<DatagramServerSocket> socket) {
1341*6777b538SAndroid Build Coastguard Worker sockets_.push_back(std::move(socket));
1342*6777b538SAndroid Build Coastguard Worker }
1343*6777b538SAndroid Build Coastguard Worker
1344*6777b538SAndroid Build Coastguard Worker private:
1345*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<DatagramServerSocket>> sockets_;
1346*6777b538SAndroid Build Coastguard Worker };
1347*6777b538SAndroid Build Coastguard Worker
1348*6777b538SAndroid Build Coastguard Worker class MockMDnsConnectionDelegate : public MDnsConnection::Delegate {
1349*6777b538SAndroid Build Coastguard Worker public:
HandlePacket(DnsResponse * response,int size)1350*6777b538SAndroid Build Coastguard Worker void HandlePacket(DnsResponse* response, int size) override {
1351*6777b538SAndroid Build Coastguard Worker HandlePacketInternal(std::string(response->io_buffer()->data(), size));
1352*6777b538SAndroid Build Coastguard Worker }
1353*6777b538SAndroid Build Coastguard Worker
1354*6777b538SAndroid Build Coastguard Worker MOCK_METHOD1(HandlePacketInternal, void(std::string packet));
1355*6777b538SAndroid Build Coastguard Worker
1356*6777b538SAndroid Build Coastguard Worker MOCK_METHOD1(OnConnectionError, void(int error));
1357*6777b538SAndroid Build Coastguard Worker };
1358*6777b538SAndroid Build Coastguard Worker
1359*6777b538SAndroid Build Coastguard Worker class MDnsConnectionTest : public TestWithTaskEnvironment {
1360*6777b538SAndroid Build Coastguard Worker public:
MDnsConnectionTest()1361*6777b538SAndroid Build Coastguard Worker MDnsConnectionTest() : connection_(&delegate_) {
1362*6777b538SAndroid Build Coastguard Worker }
1363*6777b538SAndroid Build Coastguard Worker
1364*6777b538SAndroid Build Coastguard Worker protected:
1365*6777b538SAndroid Build Coastguard Worker // Follow successful connection initialization.
SetUp()1366*6777b538SAndroid Build Coastguard Worker void SetUp() override {
1367*6777b538SAndroid Build Coastguard Worker auto socket_ipv4 =
1368*6777b538SAndroid Build Coastguard Worker std::make_unique<MockMDnsDatagramServerSocket>(ADDRESS_FAMILY_IPV4);
1369*6777b538SAndroid Build Coastguard Worker auto socket_ipv6 =
1370*6777b538SAndroid Build Coastguard Worker std::make_unique<MockMDnsDatagramServerSocket>(ADDRESS_FAMILY_IPV6);
1371*6777b538SAndroid Build Coastguard Worker socket_ipv4_ptr_ = socket_ipv4.get();
1372*6777b538SAndroid Build Coastguard Worker socket_ipv6_ptr_ = socket_ipv6.get();
1373*6777b538SAndroid Build Coastguard Worker factory_.PushSocket(std::move(socket_ipv4));
1374*6777b538SAndroid Build Coastguard Worker factory_.PushSocket(std::move(socket_ipv6));
1375*6777b538SAndroid Build Coastguard Worker sample_packet_ = MakeString(kSamplePacket1, sizeof(kSamplePacket1));
1376*6777b538SAndroid Build Coastguard Worker sample_buffer_ = base::MakeRefCounted<StringIOBuffer>(sample_packet_);
1377*6777b538SAndroid Build Coastguard Worker }
1378*6777b538SAndroid Build Coastguard Worker
InitConnection()1379*6777b538SAndroid Build Coastguard Worker int InitConnection() { return connection_.Init(&factory_); }
1380*6777b538SAndroid Build Coastguard Worker
1381*6777b538SAndroid Build Coastguard Worker StrictMock<MockMDnsConnectionDelegate> delegate_;
1382*6777b538SAndroid Build Coastguard Worker
1383*6777b538SAndroid Build Coastguard Worker raw_ptr<MockMDnsDatagramServerSocket, DanglingUntriaged> socket_ipv4_ptr_;
1384*6777b538SAndroid Build Coastguard Worker raw_ptr<MockMDnsDatagramServerSocket, DanglingUntriaged> socket_ipv6_ptr_;
1385*6777b538SAndroid Build Coastguard Worker SimpleMockSocketFactory factory_;
1386*6777b538SAndroid Build Coastguard Worker MDnsConnection connection_;
1387*6777b538SAndroid Build Coastguard Worker TestCompletionCallback callback_;
1388*6777b538SAndroid Build Coastguard Worker std::string sample_packet_;
1389*6777b538SAndroid Build Coastguard Worker scoped_refptr<IOBuffer> sample_buffer_;
1390*6777b538SAndroid Build Coastguard Worker };
1391*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsConnectionTest,ReceiveSynchronous)1392*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsConnectionTest, ReceiveSynchronous) {
1393*6777b538SAndroid Build Coastguard Worker socket_ipv6_ptr_->SetResponsePacket(sample_packet_);
1394*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_, RecvFrom(_, _, _, _))
1395*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1396*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_, RecvFrom(_, _, _, _))
1397*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(socket_ipv6_ptr_.get(),
1398*6777b538SAndroid Build Coastguard Worker &MockMDnsDatagramServerSocket::HandleRecvNow))
1399*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1400*6777b538SAndroid Build Coastguard Worker
1401*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_, HandlePacketInternal(sample_packet_));
1402*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(InitConnection(), test::IsOk());
1403*6777b538SAndroid Build Coastguard Worker }
1404*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsConnectionTest,ReceiveAsynchronous)1405*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsConnectionTest, ReceiveAsynchronous) {
1406*6777b538SAndroid Build Coastguard Worker socket_ipv6_ptr_->SetResponsePacket(sample_packet_);
1407*6777b538SAndroid Build Coastguard Worker
1408*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_, RecvFrom(_, _, _, _))
1409*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1410*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_, RecvFrom(_, _, _, _))
1411*6777b538SAndroid Build Coastguard Worker .Times(2)
1412*6777b538SAndroid Build Coastguard Worker .WillOnce(Invoke(socket_ipv6_ptr_.get(),
1413*6777b538SAndroid Build Coastguard Worker &MockMDnsDatagramServerSocket::HandleRecvLater))
1414*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1415*6777b538SAndroid Build Coastguard Worker
1416*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(InitConnection(), test::IsOk());
1417*6777b538SAndroid Build Coastguard Worker
1418*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_, HandlePacketInternal(sample_packet_));
1419*6777b538SAndroid Build Coastguard Worker
1420*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1421*6777b538SAndroid Build Coastguard Worker }
1422*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsConnectionTest,Error)1423*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsConnectionTest, Error) {
1424*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback;
1425*6777b538SAndroid Build Coastguard Worker
1426*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_, RecvFrom(_, _, _, _))
1427*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1428*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_, RecvFrom(_, _, _, _))
1429*6777b538SAndroid Build Coastguard Worker .WillOnce([&](auto, auto, auto, auto cb) {
1430*6777b538SAndroid Build Coastguard Worker callback = std::move(cb);
1431*6777b538SAndroid Build Coastguard Worker return ERR_IO_PENDING;
1432*6777b538SAndroid Build Coastguard Worker });
1433*6777b538SAndroid Build Coastguard Worker
1434*6777b538SAndroid Build Coastguard Worker ASSERT_THAT(InitConnection(), test::IsOk());
1435*6777b538SAndroid Build Coastguard Worker
1436*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_, OnConnectionError(ERR_SOCKET_NOT_CONNECTED));
1437*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(ERR_SOCKET_NOT_CONNECTED);
1438*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1439*6777b538SAndroid Build Coastguard Worker }
1440*6777b538SAndroid Build Coastguard Worker
1441*6777b538SAndroid Build Coastguard Worker class MDnsConnectionSendTest : public MDnsConnectionTest {
1442*6777b538SAndroid Build Coastguard Worker protected:
SetUp()1443*6777b538SAndroid Build Coastguard Worker void SetUp() override {
1444*6777b538SAndroid Build Coastguard Worker MDnsConnectionTest::SetUp();
1445*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_, RecvFrom(_, _, _, _))
1446*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1447*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_, RecvFrom(_, _, _, _))
1448*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_IO_PENDING));
1449*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(InitConnection(), test::IsOk());
1450*6777b538SAndroid Build Coastguard Worker }
1451*6777b538SAndroid Build Coastguard Worker };
1452*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsConnectionSendTest,Send)1453*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsConnectionSendTest, Send) {
1454*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_,
1455*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "224.0.0.251:5353", _));
1456*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_,
1457*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "[ff02::fb]:5353", _));
1458*6777b538SAndroid Build Coastguard Worker
1459*6777b538SAndroid Build Coastguard Worker connection_.Send(sample_buffer_, sample_packet_.size());
1460*6777b538SAndroid Build Coastguard Worker }
1461*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsConnectionSendTest,SendError)1462*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsConnectionSendTest, SendError) {
1463*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_,
1464*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "224.0.0.251:5353", _));
1465*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_,
1466*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
1467*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ERR_SOCKET_NOT_CONNECTED));
1468*6777b538SAndroid Build Coastguard Worker
1469*6777b538SAndroid Build Coastguard Worker connection_.Send(sample_buffer_, sample_packet_.size());
1470*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(delegate_, OnConnectionError(ERR_SOCKET_NOT_CONNECTED));
1471*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
1472*6777b538SAndroid Build Coastguard Worker }
1473*6777b538SAndroid Build Coastguard Worker
TEST_F(MDnsConnectionSendTest,SendQueued)1474*6777b538SAndroid Build Coastguard Worker TEST_F(MDnsConnectionSendTest, SendQueued) {
1475*6777b538SAndroid Build Coastguard Worker // Send data immediately.
1476*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_,
1477*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "224.0.0.251:5353", _))
1478*6777b538SAndroid Build Coastguard Worker .Times(2)
1479*6777b538SAndroid Build Coastguard Worker .WillRepeatedly(Return(OK));
1480*6777b538SAndroid Build Coastguard Worker
1481*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback;
1482*6777b538SAndroid Build Coastguard Worker // Delay sending data. Only the first call should be made.
1483*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_,
1484*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
1485*6777b538SAndroid Build Coastguard Worker .WillOnce([&](auto, auto, auto cb) {
1486*6777b538SAndroid Build Coastguard Worker callback = std::move(cb);
1487*6777b538SAndroid Build Coastguard Worker return ERR_IO_PENDING;
1488*6777b538SAndroid Build Coastguard Worker });
1489*6777b538SAndroid Build Coastguard Worker
1490*6777b538SAndroid Build Coastguard Worker connection_.Send(sample_buffer_, sample_packet_.size());
1491*6777b538SAndroid Build Coastguard Worker connection_.Send(sample_buffer_, sample_packet_.size());
1492*6777b538SAndroid Build Coastguard Worker
1493*6777b538SAndroid Build Coastguard Worker // The second IPv6 packet is not sent yet.
1494*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv4_ptr_,
1495*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "224.0.0.251:5353", _))
1496*6777b538SAndroid Build Coastguard Worker .Times(0);
1497*6777b538SAndroid Build Coastguard Worker // Expect call for the second IPv6 packet.
1498*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*socket_ipv6_ptr_,
1499*6777b538SAndroid Build Coastguard Worker SendToInternal(sample_packet_, "[ff02::fb]:5353", _))
1500*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(OK));
1501*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(OK);
1502*6777b538SAndroid Build Coastguard Worker }
1503*6777b538SAndroid Build Coastguard Worker
TEST(MDnsSocketTest,CreateSocket)1504*6777b538SAndroid Build Coastguard Worker TEST(MDnsSocketTest, CreateSocket) {
1505*6777b538SAndroid Build Coastguard Worker // Verifies that socket creation hasn't been broken.
1506*6777b538SAndroid Build Coastguard Worker auto socket = CreateAndBindMDnsSocket(AddressFamily::ADDRESS_FAMILY_IPV4, 1,
1507*6777b538SAndroid Build Coastguard Worker net::NetLog::Get());
1508*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(socket);
1509*6777b538SAndroid Build Coastguard Worker socket->Close();
1510*6777b538SAndroid Build Coastguard Worker }
1511*6777b538SAndroid Build Coastguard Worker
1512*6777b538SAndroid Build Coastguard Worker } // namespace net
1513