- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / tests / test_udp_socket_private.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 <cstring>
6 #include <vector>
7
8 #include "ppapi/cpp/module.h"
9 #include "ppapi/cpp/private/net_address_private.h"
10 #include "ppapi/cpp/private/tcp_socket_private.h"
11 #include "ppapi/cpp/var.h"
12 #include "ppapi/tests/test_udp_socket_private.h"
13 #include "ppapi/tests/test_utils.h"
14 #include "ppapi/tests/testing_instance.h"
15
16 REGISTER_TEST_CASE(UDPSocketPrivate);
17
18 namespace {
19
20 const uint16_t kPortScanFrom = 1024;
21 const uint16_t kPortScanTo = 4096;
22
23 }  // namespace
24
25 TestUDPSocketPrivate::TestUDPSocketPrivate(
26     TestingInstance* instance)
27     : TestCase(instance) {
28 }
29
30 bool TestUDPSocketPrivate::Init() {
31   bool tcp_socket_private_is_available = pp::TCPSocketPrivate::IsAvailable();
32   if (!tcp_socket_private_is_available)
33     instance_->AppendError("PPB_TCPSocket_Private interface not available");
34
35   bool udp_socket_private_is_available = pp::UDPSocketPrivate::IsAvailable();
36   if (!udp_socket_private_is_available)
37     instance_->AppendError("PPB_UDPSocket_Private interface not available");
38
39   bool net_address_private_is_available = pp::NetAddressPrivate::IsAvailable();
40   if (!net_address_private_is_available)
41     instance_->AppendError("PPB_NetAddress_Private interface not available");
42
43   bool init_host_port = GetLocalHostPort(instance_->pp_instance(),
44                                          &host_, &port_);
45   if (!init_host_port)
46     instance_->AppendError("Can't init host and port");
47
48   return tcp_socket_private_is_available &&
49       udp_socket_private_is_available &&
50       net_address_private_is_available &&
51       init_host_port &&
52       CheckTestingInterface() &&
53       EnsureRunningOverHTTP();
54 }
55
56 void TestUDPSocketPrivate::RunTests(const std::string& filter) {
57   RUN_CALLBACK_TEST(TestUDPSocketPrivate, Connect, filter);
58   RUN_CALLBACK_TEST(TestUDPSocketPrivate, ConnectFailure, filter);
59   RUN_CALLBACK_TEST(TestUDPSocketPrivate, Broadcast, filter);
60   RUN_CALLBACK_TEST(TestUDPSocketPrivate, SetSocketFeatureErrors, filter);
61 }
62
63 std::string TestUDPSocketPrivate::GetLocalAddress(
64     PP_NetAddress_Private* address) {
65   pp::TCPSocketPrivate socket(instance_);
66   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
67   callback.WaitForResult(
68       socket.Connect(host_.c_str(), port_, callback.GetCallback()));
69   CHECK_CALLBACK_BEHAVIOR(callback);
70   ASSERT_EQ(PP_OK, callback.result());
71   ASSERT_TRUE(socket.GetLocalAddress(address));
72   socket.Disconnect();
73   PASS();
74 }
75
76 std::string TestUDPSocketPrivate::SetBroadcastOptions(
77     pp::UDPSocketPrivate* socket) {
78   int32_t rv = socket->SetSocketFeature(
79       PP_UDPSOCKETFEATURE_PRIVATE_ADDRESS_REUSE, pp::Var(true));
80   if (rv != PP_OK)
81     return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
82
83   rv = socket->SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_BROADCAST,
84                                 pp::Var(true));
85   if (rv != PP_OK)
86     return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
87
88   PASS();
89 }
90
91 std::string TestUDPSocketPrivate::BindUDPSocket(
92     pp::UDPSocketPrivate* socket,
93     PP_NetAddress_Private* address) {
94   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
95   callback.WaitForResult(socket->Bind(address, callback.GetCallback()));
96   CHECK_CALLBACK_BEHAVIOR(callback);
97   ASSERT_EQ(PP_OK, callback.result());
98   PASS();
99 }
100
101 std::string TestUDPSocketPrivate::LookupPortAndBindUDPSocket(
102     pp::UDPSocketPrivate* socket,
103     PP_NetAddress_Private *address) {
104   PP_NetAddress_Private base_address;
105   ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address));
106
107   bool is_free_port_found = false;
108   for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) {
109     if (!pp::NetAddressPrivate::ReplacePort(base_address, port, address))
110       return "PPB_NetAddress_Private::ReplacePort: Failed";
111     if (BindUDPSocket(socket, address).empty()) {
112       is_free_port_found = true;
113       break;
114     }
115   }
116   if (!is_free_port_found)
117     return "Can't find available port";
118   if (!socket->GetBoundAddress(address))
119     return "PPB_UDPSocket_Private::GetBoundAddress: Failed";
120   PASS();
121 }
122
123 std::string TestUDPSocketPrivate::BindUDPSocketFailure(
124     pp::UDPSocketPrivate* socket,
125     PP_NetAddress_Private *address) {
126   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
127   callback.WaitForResult(socket->Bind(address, callback.GetCallback()));
128   CHECK_CALLBACK_BEHAVIOR(callback);
129   ASSERT_NE(PP_OK, callback.result());
130   ASSERT_FALSE(socket->GetBoundAddress(address));
131   PASS();
132 }
133
134 std::string TestUDPSocketPrivate::ReadSocket(pp::UDPSocketPrivate* socket,
135                                              PP_NetAddress_Private* address,
136                                              size_t size,
137                                              std::string* message) {
138   std::vector<char> buffer(size);
139   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
140   callback.WaitForResult(
141       socket->RecvFrom(&buffer[0], size, callback.GetCallback()));
142   CHECK_CALLBACK_BEHAVIOR(callback);
143   ASSERT_FALSE(callback.result() < 0);
144   ASSERT_EQ(size, static_cast<size_t>(callback.result()));
145   message->assign(buffer.begin(), buffer.end());
146   PASS();
147 }
148
149 std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
150                                               pp::UDPSocketPrivate* source,
151                                               PP_NetAddress_Private* address,
152                                               const std::string& message) {
153   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
154   int32_t rv = source->SendTo(message.c_str(), message.size(), address,
155                               callback.GetCallback());
156   std::string str;
157   ASSERT_SUBTEST_SUCCESS(ReadSocket(target, address, message.size(), &str));
158
159   callback.WaitForResult(rv);
160   CHECK_CALLBACK_BEHAVIOR(callback);
161   ASSERT_FALSE(callback.result() < 0);
162   ASSERT_EQ(message.size(), static_cast<size_t>(callback.result()));
163   ASSERT_EQ(message, str);
164   PASS();
165 }
166
167 std::string TestUDPSocketPrivate::TestConnect() {
168   pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
169   PP_NetAddress_Private server_address, client_address;
170
171   ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
172                                                     &server_address));
173   ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
174                                                     &client_address));
175   const std::string message = "Simple message that will be sent via UDP";
176   ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket, &client_socket,
177                                      &server_address,
178                                      message));
179   PP_NetAddress_Private recv_from_address;
180   ASSERT_TRUE(server_socket.GetRecvFromAddress(&recv_from_address));
181   ASSERT_TRUE(pp::NetAddressPrivate::AreEqual(recv_from_address,
182                                               client_address));
183
184   server_socket.Close();
185   client_socket.Close();
186
187   if (server_socket.GetBoundAddress(&server_address))
188     return "PPB_UDPSocket_Private::GetBoundAddress: expected Failure";
189   PASS();
190 }
191
192 std::string TestUDPSocketPrivate::TestConnectFailure() {
193   pp::UDPSocketPrivate socket(instance_);
194   PP_NetAddress_Private invalid_address = {};
195
196   std::string error_message = BindUDPSocketFailure(&socket, &invalid_address);
197   if (!error_message.empty())
198     return error_message;
199
200   PASS();
201 }
202
203 std::string TestUDPSocketPrivate::TestBroadcast() {
204   const uint8_t broadcast_ip[4] = { 0xff, 0xff, 0xff, 0xff };
205
206   pp::UDPSocketPrivate server1(instance_), server2(instance_);
207
208   ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server1));
209   ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server2));
210   PP_NetAddress_Private server_address;
211   ASSERT_TRUE(pp::NetAddressPrivate::GetAnyAddress(false, &server_address));
212   ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server1, &server_address));
213   // Fill port field of |server_address|.
214   ASSERT_TRUE(server1.GetBoundAddress(&server_address));
215   ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server2, &server_address));
216
217   const uint16_t port = pp::NetAddressPrivate::GetPort(server_address);
218   PP_NetAddress_Private broadcast_address;
219   ASSERT_TRUE(pp::NetAddressPrivate::CreateFromIPv4Address(
220       broadcast_ip, port, &broadcast_address));
221
222   std::string message;
223   const std::string first_message = "first message";
224   const std::string second_message = "second_message";
225
226   ASSERT_SUBTEST_SUCCESS(PassMessage(&server1, &server2,
227                                      &broadcast_address,
228                                      first_message));
229   // |first_message| also arrived to |server2|.
230   ASSERT_SUBTEST_SUCCESS(ReadSocket(&server2, &broadcast_address,
231                                     first_message.size(), &message));
232   ASSERT_EQ(first_message, message);
233
234   ASSERT_SUBTEST_SUCCESS(PassMessage(&server2, &server1,
235                                      &broadcast_address,
236                                      second_message));
237   // |second_message| also arrived to |server1|.
238   ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &broadcast_address,
239                                     second_message.size(), &message));
240   ASSERT_EQ(second_message, message);
241
242   server1.Close();
243   server2.Close();
244   PASS();
245 }
246
247 std::string TestUDPSocketPrivate::TestSetSocketFeatureErrors() {
248   pp::UDPSocketPrivate socket(instance_);
249   // Try to pass incorrect feature name.
250   int32_t rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_COUNT,
251                                        pp::Var(true));
252   ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
253
254   // Try to pass incorrect feature value's type.
255   rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_ADDRESS_REUSE,
256                                pp::Var(1));
257   ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
258   PASS();
259 }