1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/location.h"
6 #include "base/single_thread_task_runner.h"
7 #include "base/thread_task_runner_handle.h"
8 #include "chrome/common/local_discovery/service_discovery_client_impl.h"
9 #include "net/dns/mdns_client_impl.h"
10 #include "net/dns/mock_mdns_socket_factory.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 namespace local_discovery
{
20 const uint8 kSamplePacketA
[] = {
22 0x00, 0x00, // ID is zeroed out
23 0x81, 0x80, // Standard query response, RA, no error
24 0x00, 0x00, // No questions (for simplicity)
25 0x00, 0x01, // 1 RR (answers)
26 0x00, 0x00, // 0 authority RRs
27 0x00, 0x00, // 0 additional RRs
29 0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o',
30 0x05, 'l', 'o', 'c', 'a', 'l',
32 0x00, 0x01, // TYPE is A.
33 0x00, 0x01, // CLASS is IN.
34 0x00, 0x00, // TTL (4 bytes) is 16 seconds.
36 0x00, 0x04, // RDLENGTH is 4 bytes.
41 const uint8 kSamplePacketAAAA
[] = {
43 0x00, 0x00, // ID is zeroed out
44 0x81, 0x80, // Standard query response, RA, no error
45 0x00, 0x00, // No questions (for simplicity)
46 0x00, 0x01, // 1 RR (answers)
47 0x00, 0x00, // 0 authority RRs
48 0x00, 0x00, // 0 additional RRs
50 0x07, 'm', 'y', 'h', 'e', 'l', 'l', 'o',
51 0x05, 'l', 'o', 'c', 'a', 'l',
53 0x00, 0x1C, // TYPE is AAAA.
54 0x00, 0x01, // CLASS is IN.
55 0x00, 0x00, // TTL (4 bytes) is 16 seconds.
57 0x00, 0x10, // RDLENGTH is 4 bytes.
58 0x00, 0x0A, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x01, 0x00, 0x02,
61 0x00, 0x03, 0x00, 0x04,
64 class LocalDomainResolverTest
: public testing::Test
{
66 void SetUp() override
{
67 mdns_client_
.StartListening(&socket_factory_
);
70 std::string
IPAddressToStringWithEmpty(const net::IPAddressNumber
& address
) {
71 if (address
.empty()) return "";
72 return net::IPAddressToString(address
);
75 void AddressCallback(bool resolved
,
76 const net::IPAddressNumber
& address_ipv4
,
77 const net::IPAddressNumber
& address_ipv6
) {
78 AddressCallbackInternal(resolved
,
79 IPAddressToStringWithEmpty(address_ipv4
),
80 IPAddressToStringWithEmpty(address_ipv6
));
83 void RunFor(base::TimeDelta time_period
) {
84 base::CancelableCallback
<void()> callback(base::Bind(
85 &base::MessageLoop::Quit
,
86 base::Unretained(base::MessageLoop::current())));
87 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
88 FROM_HERE
, callback
.callback(), time_period
);
90 base::MessageLoop::current()->Run();
94 MOCK_METHOD3(AddressCallbackInternal
,
96 std::string address_ipv4
,
97 std::string address_ipv6
));
99 net::MockMDnsSocketFactory socket_factory_
;
100 net::MDnsClientImpl mdns_client_
;
101 base::MessageLoop message_loop_
;
104 TEST_F(LocalDomainResolverTest
, ResolveDomainA
) {
105 LocalDomainResolverImpl
resolver(
106 "myhello.local", net::ADDRESS_FAMILY_IPV4
,
107 base::Bind(&LocalDomainResolverTest::AddressCallback
,
108 base::Unretained(this)), &mdns_client_
);
110 EXPECT_CALL(socket_factory_
, OnSendTo(_
)).Times(2); // Twice per query
114 EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4", ""));
116 socket_factory_
.SimulateReceive(kSamplePacketA
, sizeof(kSamplePacketA
));
119 TEST_F(LocalDomainResolverTest
, ResolveDomainAAAA
) {
120 LocalDomainResolverImpl
resolver(
121 "myhello.local", net::ADDRESS_FAMILY_IPV6
,
122 base::Bind(&LocalDomainResolverTest::AddressCallback
,
123 base::Unretained(this)), &mdns_client_
);
125 EXPECT_CALL(socket_factory_
, OnSendTo(_
)).Times(2); // Twice per query
129 EXPECT_CALL(*this, AddressCallbackInternal(true, "", "a::1:2:3:4"));
131 socket_factory_
.SimulateReceive(kSamplePacketAAAA
, sizeof(kSamplePacketAAAA
));
134 TEST_F(LocalDomainResolverTest
, ResolveDomainAnyOneAvailable
) {
135 LocalDomainResolverImpl
resolver(
136 "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED
,
137 base::Bind(&LocalDomainResolverTest::AddressCallback
,
138 base::Unretained(this)), &mdns_client_
);
140 EXPECT_CALL(socket_factory_
, OnSendTo(_
)).Times(4); // Twice per query
144 socket_factory_
.SimulateReceive(kSamplePacketAAAA
, sizeof(kSamplePacketAAAA
));
146 EXPECT_CALL(*this, AddressCallbackInternal(true, "", "a::1:2:3:4"));
148 RunFor(base::TimeDelta::FromMilliseconds(150));
152 TEST_F(LocalDomainResolverTest
, ResolveDomainAnyBothAvailable
) {
153 LocalDomainResolverImpl
resolver(
154 "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED
,
155 base::Bind(&LocalDomainResolverTest::AddressCallback
,
156 base::Unretained(this)), &mdns_client_
);
158 EXPECT_CALL(socket_factory_
, OnSendTo(_
)).Times(4); // Twice per query
162 EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4", "a::1:2:3:4"));
164 socket_factory_
.SimulateReceive(kSamplePacketAAAA
, sizeof(kSamplePacketAAAA
));
166 socket_factory_
.SimulateReceive(kSamplePacketA
, sizeof(kSamplePacketA
));
169 TEST_F(LocalDomainResolverTest
, ResolveDomainNone
) {
170 LocalDomainResolverImpl
resolver(
171 "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED
,
172 base::Bind(&LocalDomainResolverTest::AddressCallback
,
173 base::Unretained(this)), &mdns_client_
);
175 EXPECT_CALL(socket_factory_
, OnSendTo(_
)).Times(4); // Twice per query
179 EXPECT_CALL(*this, AddressCallbackInternal(false, "", ""));
181 RunFor(base::TimeDelta::FromSeconds(4));
186 } // namespace local_discovery