Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / dial / dial_service_unittest.cc
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.
4
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/capturing_net_log.h"
11 #include "net/base/ip_endpoint.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using base::Time;
16 using base::TimeDelta;
17 using ::testing::A;
18 using ::testing::AtLeast;
19 using ::testing::Return;
20
21 namespace {
22
23 const char kValidResponse[] =
24   "HTTP/1.1 OK\r\n"
25   "LOCATION: http://127.0.0.1/dd.xml\r\n"
26   "USN: some_id\r\n"
27   "CACHE-CONTROL: max-age=1800\r\n"
28   "CONFIGID.UPNP.ORG: 1\r\n\r\n";
29
30 }  // namespace
31
32 namespace extensions {
33
34 class MockObserver : public DialService::Observer {
35  public:
36   MOCK_METHOD1(OnDiscoveryRequest, void(DialService*));
37   MOCK_METHOD2(OnDeviceDiscovered, void(DialService*, const DialDeviceData&));
38   MOCK_METHOD1(OnDiscoveryFinished, void(DialService*));
39   MOCK_METHOD2(OnError, void(DialService*,
40                              const DialService::DialServiceErrorCode&));
41 };
42
43 class DialServiceTest : public testing::Test {
44  public:
45   DialServiceTest()
46     : dial_service_(&capturing_net_log_) {
47     CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &mock_ip_));
48     dial_service_.AddObserver(&mock_observer_);
49     dial_socket_ = dial_service_.CreateDialSocket();
50   }
51  protected:
52   net::CapturingNetLog capturing_net_log_;
53   net::IPAddressNumber mock_ip_;
54   DialServiceImpl dial_service_;
55   scoped_ptr<DialServiceImpl::DialSocket> dial_socket_;
56   MockObserver mock_observer_;
57 };
58
59 TEST_F(DialServiceTest, TestSendMultipleRequests) {
60   base::MessageLoopForIO loop;
61   // Setting the finish delay to zero disables the timer that invokes
62   // FinishDiscovery().
63   dial_service_.finish_delay_ = TimeDelta::FromSeconds(0);
64   dial_service_.request_interval_ = TimeDelta::FromSeconds(0);
65   dial_service_.max_requests_ = 4;
66   dial_service_.discovery_active_ = true;
67   EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(4);
68   EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
69   dial_service_.BindAndAddSocket(mock_ip_);
70   EXPECT_EQ(1u, dial_service_.dial_sockets_.size());
71   dial_service_.SendOneRequest();
72   loop.RunUntilIdle();
73   dial_service_.FinishDiscovery();
74 }
75
76 TEST_F(DialServiceTest, TestMultipleNetworkInterfaces) {
77   base::MessageLoopForIO loop;
78   // Setting the finish delay to zero disables the timer that invokes
79   // FinishDiscovery().
80   dial_service_.finish_delay_ = TimeDelta::FromSeconds(0);
81   dial_service_.request_interval_ = TimeDelta::FromSeconds(0);
82   dial_service_.max_requests_ = 4;
83   dial_service_.discovery_active_ = true;
84   net::NetworkInterfaceList interface_list;
85   interface_list.push_back(
86       net::NetworkInterface("network1",
87                             "network1",
88                             0,
89                             net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
90                             mock_ip_,
91                             0,
92                             net::IP_ADDRESS_ATTRIBUTE_NONE));
93   interface_list.push_back(
94       net::NetworkInterface("network2",
95                             "network2",
96                             1,
97                             net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
98                             mock_ip_,
99                             0,
100                             net::IP_ADDRESS_ATTRIBUTE_NONE));
101   interface_list.push_back(
102       net::NetworkInterface("network3",
103                             "network3",
104                             2,
105                             net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
106                             mock_ip_,
107                             0,
108                             net::IP_ADDRESS_ATTRIBUTE_NONE));
109
110   // "network4" is equivalent to "network2" because both the address family
111   // and interface index are the same.
112   interface_list.push_back(
113       net::NetworkInterface("network4",
114                             "network4",
115                             1,
116                             net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
117                             mock_ip_,
118                             0,
119                             net::IP_ADDRESS_ATTRIBUTE_NONE));
120
121   // 3 sockets * 4 requests per socket = 12 requests
122   EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(12);
123   EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
124
125   dial_service_.SendNetworkList(interface_list);
126   EXPECT_EQ(3u, dial_service_.dial_sockets_.size());
127
128   loop.RunUntilIdle();
129   dial_service_.FinishDiscovery();
130 }
131
132 TEST_F(DialServiceTest, TestOnDiscoveryRequest) {
133   dial_service_.discovery_active_ = true;
134   dial_service_.num_requests_sent_ = 1;
135   dial_service_.max_requests_ = 1;
136   size_t num_bytes = dial_service_.send_buffer_->size();
137   EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(1);
138   dial_socket_->OnSocketWrite(num_bytes, num_bytes);
139 }
140
141 TEST_F(DialServiceTest, TestOnDeviceDiscovered) {
142   dial_service_.discovery_active_ = true;
143   int response_size = arraysize(kValidResponse) - 1;
144   dial_socket_->recv_buffer_ =
145       new net::IOBufferWithSize(response_size);
146   strncpy(dial_socket_->recv_buffer_->data(),
147           kValidResponse,
148           response_size);
149   dial_socket_->recv_address_ = net::IPEndPoint(mock_ip_, 12345);
150
151   DialDeviceData expected_device;
152   expected_device.set_device_id("some_id");
153
154   EXPECT_CALL(mock_observer_,
155               OnDeviceDiscovered(A<DialService*>(), expected_device))
156       .Times(1);
157   dial_socket_->OnSocketRead(response_size);
158 };
159
160 TEST_F(DialServiceTest, TestOnDiscoveryFinished) {
161   dial_service_.discovery_active_ = true;
162
163   EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
164   dial_service_.FinishDiscovery();
165   EXPECT_FALSE(dial_service_.discovery_active_);
166 }
167
168 TEST_F(DialServiceTest, TestResponseParsing) {
169   Time now = Time::Now();
170
171   // Successful case
172   DialDeviceData parsed;
173   EXPECT_TRUE(DialServiceImpl::DialSocket::ParseResponse(
174       kValidResponse, now, &parsed));
175   EXPECT_EQ("some_id", parsed.device_id());
176   EXPECT_EQ("http://127.0.0.1/dd.xml", parsed.device_description_url().spec());
177   EXPECT_EQ(1, parsed.config_id());
178   EXPECT_EQ(now, parsed.response_time());
179
180   // Failure cases
181   DialDeviceData not_parsed;
182
183   // Empty, garbage
184   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
185       std::string(), now, &not_parsed));
186   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
187       "\r\n\r\n",
188     now, &not_parsed));
189   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
190       "xyzzy",
191       now, &not_parsed));
192
193   // No headers
194   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
195       "HTTP/1.1 OK\r\n\r\n",
196       now, &not_parsed));
197
198   // Missing LOCATION
199   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
200       "HTTP/1.1 OK\r\n"
201       "USN: some_id\r\n\r\n",
202       now, &not_parsed));
203
204   // Empty LOCATION
205   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
206       "HTTP/1.1 OK\r\n"
207       "LOCATION:\r\n"
208       "USN: some_id\r\n\r\n",
209       now, &not_parsed));
210
211   // Missing USN
212   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
213       "HTTP/1.1 OK\r\n"
214       "LOCATION: http://127.0.0.1/dd.xml\r\n\r\n",
215       now, &not_parsed));
216
217   // Empty USN
218   EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
219       "HTTP/1.1 OK\r\n"
220       "LOCATION: http://127.0.0.1/dd.xml\r\n"
221       "USN:\r\n\r\n",
222       now, &not_parsed));
223 }
224
225 }  // namespace extensions