1 // Copyright (c) 2012 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/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop/message_loop.h"
8 #include "chrome/browser/extensions/api/dial/dial_device_data.h"
9 #include "chrome/browser/extensions/api/dial/dial_service.h"
10 #include "net/base/ip_endpoint.h"
11 #include "net/base/network_interfaces.h"
12 #include "net/log/test_net_log.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
17 using base::TimeDelta
;
19 using ::testing::AtLeast
;
20 using ::testing::Return
;
24 const char kValidResponse
[] =
26 "LOCATION: http://127.0.0.1/dd.xml\r\n"
28 "CACHE-CONTROL: max-age=1800\r\n"
29 "CONFIGID.UPNP.ORG: 1\r\n\r\n";
33 namespace extensions
{
35 class MockObserver
: public DialService::Observer
{
37 MOCK_METHOD1(OnDiscoveryRequest
, void(DialService
*));
38 MOCK_METHOD2(OnDeviceDiscovered
, void(DialService
*, const DialDeviceData
&));
39 MOCK_METHOD1(OnDiscoveryFinished
, void(DialService
*));
40 MOCK_METHOD2(OnError
, void(DialService
*,
41 const DialService::DialServiceErrorCode
&));
44 class DialServiceTest
: public testing::Test
{
47 : dial_service_(&test_net_log_
) {
48 CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &mock_ip_
));
49 dial_service_
.AddObserver(&mock_observer_
);
50 dial_socket_
= dial_service_
.CreateDialSocket();
53 net::TestNetLog test_net_log_
;
54 net::IPAddressNumber mock_ip_
;
55 DialServiceImpl dial_service_
;
56 scoped_ptr
<DialServiceImpl::DialSocket
> dial_socket_
;
57 MockObserver mock_observer_
;
60 TEST_F(DialServiceTest
, TestSendMultipleRequests
) {
61 base::MessageLoopForIO loop
;
62 // Setting the finish delay to zero disables the timer that invokes
64 dial_service_
.finish_delay_
= TimeDelta::FromSeconds(0);
65 dial_service_
.request_interval_
= TimeDelta::FromSeconds(0);
66 dial_service_
.max_requests_
= 4;
67 dial_service_
.discovery_active_
= true;
68 EXPECT_CALL(mock_observer_
, OnDiscoveryRequest(A
<DialService
*>())).Times(4);
69 EXPECT_CALL(mock_observer_
, OnDiscoveryFinished(A
<DialService
*>())).Times(1);
70 dial_service_
.BindAndAddSocket(mock_ip_
);
71 EXPECT_EQ(1u, dial_service_
.dial_sockets_
.size());
72 dial_service_
.SendOneRequest();
74 dial_service_
.FinishDiscovery();
77 TEST_F(DialServiceTest
, TestMultipleNetworkInterfaces
) {
78 base::MessageLoopForIO loop
;
79 // Setting the finish delay to zero disables the timer that invokes
81 dial_service_
.finish_delay_
= TimeDelta::FromSeconds(0);
82 dial_service_
.request_interval_
= TimeDelta::FromSeconds(0);
83 dial_service_
.max_requests_
= 4;
84 dial_service_
.discovery_active_
= true;
85 net::NetworkInterfaceList interface_list
;
86 interface_list
.push_back(
87 net::NetworkInterface("network1",
90 net::NetworkChangeNotifier::CONNECTION_UNKNOWN
,
93 net::IP_ADDRESS_ATTRIBUTE_NONE
));
94 interface_list
.push_back(
95 net::NetworkInterface("network2",
98 net::NetworkChangeNotifier::CONNECTION_UNKNOWN
,
101 net::IP_ADDRESS_ATTRIBUTE_NONE
));
102 interface_list
.push_back(
103 net::NetworkInterface("network3",
106 net::NetworkChangeNotifier::CONNECTION_UNKNOWN
,
109 net::IP_ADDRESS_ATTRIBUTE_NONE
));
111 // "network4" is equivalent to "network2" because both the address family
112 // and interface index are the same.
113 interface_list
.push_back(
114 net::NetworkInterface("network4",
117 net::NetworkChangeNotifier::CONNECTION_UNKNOWN
,
120 net::IP_ADDRESS_ATTRIBUTE_NONE
));
122 // 3 sockets * 4 requests per socket = 12 requests
123 EXPECT_CALL(mock_observer_
, OnDiscoveryRequest(A
<DialService
*>())).Times(12);
124 EXPECT_CALL(mock_observer_
, OnDiscoveryFinished(A
<DialService
*>())).Times(1);
126 dial_service_
.SendNetworkList(interface_list
);
127 EXPECT_EQ(3u, dial_service_
.dial_sockets_
.size());
130 dial_service_
.FinishDiscovery();
133 TEST_F(DialServiceTest
, TestOnDiscoveryRequest
) {
134 dial_service_
.discovery_active_
= true;
135 dial_service_
.num_requests_sent_
= 1;
136 dial_service_
.max_requests_
= 1;
137 size_t num_bytes
= dial_service_
.send_buffer_
->size();
138 EXPECT_CALL(mock_observer_
, OnDiscoveryRequest(A
<DialService
*>())).Times(1);
139 dial_socket_
->OnSocketWrite(num_bytes
, num_bytes
);
142 TEST_F(DialServiceTest
, TestOnDeviceDiscovered
) {
143 dial_service_
.discovery_active_
= true;
144 int response_size
= arraysize(kValidResponse
) - 1;
145 dial_socket_
->recv_buffer_
=
146 new net::IOBufferWithSize(response_size
);
147 strncpy(dial_socket_
->recv_buffer_
->data(),
150 dial_socket_
->recv_address_
= net::IPEndPoint(mock_ip_
, 12345);
152 DialDeviceData expected_device
;
153 expected_device
.set_device_id("some_id");
155 EXPECT_CALL(mock_observer_
,
156 OnDeviceDiscovered(A
<DialService
*>(), expected_device
))
158 dial_socket_
->OnSocketRead(response_size
);
161 TEST_F(DialServiceTest
, TestOnDiscoveryFinished
) {
162 dial_service_
.discovery_active_
= true;
164 EXPECT_CALL(mock_observer_
, OnDiscoveryFinished(A
<DialService
*>())).Times(1);
165 dial_service_
.FinishDiscovery();
166 EXPECT_FALSE(dial_service_
.discovery_active_
);
169 TEST_F(DialServiceTest
, TestResponseParsing
) {
170 Time now
= Time::Now();
173 DialDeviceData parsed
;
174 EXPECT_TRUE(DialServiceImpl::DialSocket::ParseResponse(
175 kValidResponse
, now
, &parsed
));
176 EXPECT_EQ("some_id", parsed
.device_id());
177 EXPECT_EQ("http://127.0.0.1/dd.xml", parsed
.device_description_url().spec());
178 EXPECT_EQ(1, parsed
.config_id());
179 EXPECT_EQ(now
, parsed
.response_time());
182 DialDeviceData not_parsed
;
185 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
186 std::string(), now
, ¬_parsed
));
187 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
190 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
195 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
196 "HTTP/1.1 OK\r\n\r\n",
200 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
202 "USN: some_id\r\n\r\n",
206 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
209 "USN: some_id\r\n\r\n",
213 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
215 "LOCATION: http://127.0.0.1/dd.xml\r\n\r\n",
219 EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
221 "LOCATION: http://127.0.0.1/dd.xml\r\n"
226 } // namespace extensions