OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/tests/test_udp_socket.h" | 5 #include "ppapi/tests/test_udp_socket.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "ppapi/cpp/pass_ref.h" | 9 #include "ppapi/cpp/pass_ref.h" |
10 #include "ppapi/cpp/tcp_socket.h" | 10 #include "ppapi/cpp/tcp_socket.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 } | 40 } |
41 default: { | 41 default: { |
42 PP_NOTREACHED(); | 42 PP_NOTREACHED(); |
43 } | 43 } |
44 } | 44 } |
45 return pp::NetAddress(); | 45 return pp::NetAddress(); |
46 } | 46 } |
47 | 47 |
48 } // namespace | 48 } // namespace |
49 | 49 |
50 TestUDPSocket::TestUDPSocket(TestingInstance* instance) : TestCase(instance) { | 50 TestUDPSocket::TestUDPSocket(TestingInstance* instance) |
| 51 : TestCase(instance), |
| 52 socket_interface_1_0_(NULL), |
| 53 socket_interface_1_1_(NULL) { |
51 } | 54 } |
52 | 55 |
53 bool TestUDPSocket::Init() { | 56 bool TestUDPSocket::Init() { |
54 bool tcp_socket_is_available = pp::TCPSocket::IsAvailable(); | 57 bool tcp_socket_is_available = pp::TCPSocket::IsAvailable(); |
55 if (!tcp_socket_is_available) | 58 if (!tcp_socket_is_available) |
56 instance_->AppendError("PPB_TCPSocket interface not available"); | 59 instance_->AppendError("PPB_TCPSocket interface not available"); |
57 | 60 |
58 bool udp_socket_is_available = pp::UDPSocket::IsAvailable(); | 61 bool udp_socket_is_available = pp::UDPSocket::IsAvailable(); |
59 if (!udp_socket_is_available) | 62 if (!udp_socket_is_available) |
60 instance_->AppendError("PPB_UDPSocket interface not available"); | 63 instance_->AppendError("PPB_UDPSocket interface not available"); |
61 | 64 |
62 bool net_address_is_available = pp::NetAddress::IsAvailable(); | 65 bool net_address_is_available = pp::NetAddress::IsAvailable(); |
63 if (!net_address_is_available) | 66 if (!net_address_is_available) |
64 instance_->AppendError("PPB_NetAddress interface not available"); | 67 instance_->AppendError("PPB_NetAddress interface not available"); |
65 | 68 |
66 std::string host; | 69 std::string host; |
67 uint16_t port = 0; | 70 uint16_t port = 0; |
68 bool init_address = | 71 bool init_address = |
69 GetLocalHostPort(instance_->pp_instance(), &host, &port) && | 72 GetLocalHostPort(instance_->pp_instance(), &host, &port) && |
70 ResolveHost(instance_->pp_instance(), host, port, &address_); | 73 ResolveHost(instance_->pp_instance(), host, port, &address_); |
71 if (!init_address) | 74 if (!init_address) |
72 instance_->AppendError("Can't init address"); | 75 instance_->AppendError("Can't init address"); |
73 | 76 |
| 77 socket_interface_1_0_ = |
| 78 static_cast<const PPB_UDPSocket_1_0*>( |
| 79 pp::Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_INTERFACE_1_0)); |
| 80 if (!socket_interface_1_0_) |
| 81 instance_->AppendError("PPB_UDPSocket_1_0 interface not available"); |
| 82 |
| 83 socket_interface_1_1_ = |
| 84 static_cast<const PPB_UDPSocket_1_1*>( |
| 85 pp::Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_INTERFACE_1_1)); |
| 86 if (!socket_interface_1_1_) |
| 87 instance_->AppendError("PPB_UDPSocket_1_1 interface not available"); |
| 88 |
74 return tcp_socket_is_available && | 89 return tcp_socket_is_available && |
75 udp_socket_is_available && | 90 udp_socket_is_available && |
76 net_address_is_available && | 91 net_address_is_available && |
77 init_address && | 92 init_address && |
78 CheckTestingInterface() && | 93 CheckTestingInterface() && |
79 EnsureRunningOverHTTP(); | 94 EnsureRunningOverHTTP() && |
| 95 socket_interface_1_0_ != NULL && |
| 96 socket_interface_1_1_ != NULL; |
80 } | 97 } |
81 | 98 |
82 void TestUDPSocket::RunTests(const std::string& filter) { | 99 void TestUDPSocket::RunTests(const std::string& filter) { |
83 RUN_CALLBACK_TEST(TestUDPSocket, ReadWrite, filter); | 100 RUN_CALLBACK_TEST(TestUDPSocket, ReadWrite, filter); |
84 RUN_CALLBACK_TEST(TestUDPSocket, Broadcast, filter); | 101 RUN_CALLBACK_TEST(TestUDPSocket, Broadcast, filter); |
| 102 RUN_CALLBACK_TEST(TestUDPSocket, SetOption_1_0, filter); |
| 103 RUN_CALLBACK_TEST(TestUDPSocket, SetOption_1_1, filter); |
85 RUN_CALLBACK_TEST(TestUDPSocket, SetOption, filter); | 104 RUN_CALLBACK_TEST(TestUDPSocket, SetOption, filter); |
86 RUN_CALLBACK_TEST(TestUDPSocket, ParallelSend, filter); | 105 RUN_CALLBACK_TEST(TestUDPSocket, ParallelSend, filter); |
| 106 RUN_CALLBACK_TEST(TestUDPSocket, Multicast, filter); |
87 } | 107 } |
88 | 108 |
89 std::string TestUDPSocket::GetLocalAddress(pp::NetAddress* address) { | 109 std::string TestUDPSocket::GetLocalAddress(pp::NetAddress* address) { |
90 pp::TCPSocket socket(instance_); | 110 pp::TCPSocket socket(instance_); |
91 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); | 111 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
92 callback.WaitForResult(socket.Connect(address_, callback.GetCallback())); | 112 callback.WaitForResult(socket.Connect(address_, callback.GetCallback())); |
93 CHECK_CALLBACK_BEHAVIOR(callback); | 113 CHECK_CALLBACK_BEHAVIOR(callback); |
94 ASSERT_EQ(PP_OK, callback.result()); | 114 ASSERT_EQ(PP_OK, callback.result()); |
95 *address = socket.GetLocalAddress(); | 115 *address = socket.GetLocalAddress(); |
96 ASSERT_NE(0, address->pp_resource()); | 116 ASSERT_NE(0, address->pp_resource()); |
(...skipping 27 matching lines...) Expand all Loading... |
124 PASS(); | 144 PASS(); |
125 } | 145 } |
126 | 146 |
127 std::string TestUDPSocket::LookupPortAndBindUDPSocket( | 147 std::string TestUDPSocket::LookupPortAndBindUDPSocket( |
128 pp::UDPSocket* socket, | 148 pp::UDPSocket* socket, |
129 pp::NetAddress* address) { | 149 pp::NetAddress* address) { |
130 pp::NetAddress base_address; | 150 pp::NetAddress base_address; |
131 ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address)); | 151 ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address)); |
132 | 152 |
133 bool is_free_port_found = false; | 153 bool is_free_port_found = false; |
| 154 std::string ret; |
134 for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) { | 155 for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) { |
135 pp::NetAddress new_address = ReplacePort(instance_, base_address, port); | 156 pp::NetAddress new_address = ReplacePort(instance_, base_address, port); |
136 ASSERT_NE(0, new_address.pp_resource()); | 157 ASSERT_NE(0, new_address.pp_resource()); |
137 if (BindUDPSocket(socket, new_address).empty()) { | 158 ret = BindUDPSocket(socket, new_address); |
| 159 if (ret.empty()) { |
138 is_free_port_found = true; | 160 is_free_port_found = true; |
139 break; | 161 break; |
140 } | 162 } |
141 } | 163 } |
142 if (!is_free_port_found) | 164 if (!is_free_port_found) |
143 return "Can't find available port"; | 165 return "Can't find available port (" + ret + ")"; |
144 | 166 |
145 *address = socket->GetBoundAddress(); | 167 *address = socket->GetBoundAddress(); |
146 ASSERT_NE(0, address->pp_resource()); | 168 ASSERT_NE(0, address->pp_resource()); |
147 | 169 |
148 PASS(); | 170 PASS(); |
149 } | 171 } |
150 | 172 |
151 std::string TestUDPSocket::ReadSocket(pp::UDPSocket* socket, | 173 std::string TestUDPSocket::ReadSocket(pp::UDPSocket* socket, |
152 pp::NetAddress* address, | 174 pp::NetAddress* address, |
153 size_t size, | 175 size_t size, |
(...skipping 27 matching lines...) Expand all Loading... |
181 &str)); | 203 &str)); |
182 | 204 |
183 callback.WaitForResult(rv); | 205 callback.WaitForResult(rv); |
184 CHECK_CALLBACK_BEHAVIOR(callback); | 206 CHECK_CALLBACK_BEHAVIOR(callback); |
185 ASSERT_FALSE(callback.result() < 0); | 207 ASSERT_FALSE(callback.result() < 0); |
186 ASSERT_EQ(message.size(), static_cast<size_t>(callback.result())); | 208 ASSERT_EQ(message.size(), static_cast<size_t>(callback.result())); |
187 ASSERT_EQ(message, str); | 209 ASSERT_EQ(message, str); |
188 PASS(); | 210 PASS(); |
189 } | 211 } |
190 | 212 |
| 213 std::string TestUDPSocket::SetMulticastOptions(pp::UDPSocket* socket) { |
| 214 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 215 callback.WaitForResult(socket->SetOption( |
| 216 PP_UDPSOCKET_OPTION_MULTICAST_LOOP, pp::Var(true), |
| 217 callback.GetCallback())); |
| 218 CHECK_CALLBACK_BEHAVIOR(callback); |
| 219 ASSERT_EQ(PP_OK, callback.result()); |
| 220 |
| 221 callback.WaitForResult(socket->SetOption( |
| 222 PP_UDPSOCKET_OPTION_MULTICAST_TTL, pp::Var(1), callback.GetCallback())); |
| 223 CHECK_CALLBACK_BEHAVIOR(callback); |
| 224 ASSERT_EQ(PP_OK, callback.result()); |
| 225 |
| 226 PASS(); |
| 227 } |
| 228 |
191 std::string TestUDPSocket::TestReadWrite() { | 229 std::string TestUDPSocket::TestReadWrite() { |
192 pp::UDPSocket server_socket(instance_), client_socket(instance_); | 230 pp::UDPSocket server_socket(instance_), client_socket(instance_); |
193 pp::NetAddress server_address, client_address; | 231 pp::NetAddress server_address, client_address; |
194 | 232 |
195 ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket, | 233 ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket, |
196 &server_address)); | 234 &server_address)); |
197 ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket, | 235 ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket, |
198 &client_address)); | 236 &client_address)); |
199 const std::string message = "Simple message that will be sent via UDP"; | 237 const std::string message = "Simple message that will be sent via UDP"; |
200 pp::NetAddress recvfrom_address; | 238 pp::NetAddress recvfrom_address; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 // |second_message| was also received by |server1|. | 289 // |second_message| was also received by |server1|. |
252 ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &recvfrom_address, | 290 ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &recvfrom_address, |
253 second_message.size(), &message)); | 291 second_message.size(), &message)); |
254 ASSERT_EQ(second_message, message); | 292 ASSERT_EQ(second_message, message); |
255 | 293 |
256 server1.Close(); | 294 server1.Close(); |
257 server2.Close(); | 295 server2.Close(); |
258 PASS(); | 296 PASS(); |
259 } | 297 } |
260 | 298 |
| 299 int32_t TestUDPSocket::SetOptionValue(UDPSocketSetOption func, |
| 300 PP_Resource socket, |
| 301 PP_UDPSocket_Option option, |
| 302 const PP_Var& value) { |
| 303 PP_TimeTicks start_time(NowInTimeTicks()); |
| 304 TestCompletionCallback cb(instance_->pp_instance(), callback_type()); |
| 305 cb.WaitForResult(func(socket, option, value, |
| 306 cb.GetCallback().pp_completion_callback())); |
| 307 |
| 308 // Expanded from CHECK_CALLBACK_BEHAVIOR macro. |
| 309 if (cb.failed()) { |
| 310 std::string msg = MakeFailureMessage(__FILE__, __LINE__, |
| 311 cb.errors().c_str()); |
| 312 |
| 313 instance_->LogTest("SetOptionValue", msg, start_time); |
| 314 return PP_ERROR_FAILED; |
| 315 } |
| 316 return cb.result(); |
| 317 } |
| 318 |
| 319 std::string TestUDPSocket::TestSetOption_1_0() { |
| 320 PP_Resource socket = socket_interface_1_0_->Create(instance_->pp_instance()); |
| 321 ASSERT_NE(0, socket); |
| 322 |
| 323 // Multicast options are not supported in interface 1.0. |
| 324 ASSERT_EQ(PP_ERROR_BADARGUMENT, |
| 325 SetOptionValue(socket_interface_1_0_->SetOption, |
| 326 socket, |
| 327 PP_UDPSOCKET_OPTION_MULTICAST_LOOP, |
| 328 PP_MakeBool(PP_TRUE))); |
| 329 |
| 330 ASSERT_EQ(PP_ERROR_BADARGUMENT, |
| 331 SetOptionValue(socket_interface_1_0_->SetOption, |
| 332 socket, |
| 333 PP_UDPSOCKET_OPTION_MULTICAST_TTL, |
| 334 PP_MakeInt32(1))); |
| 335 |
| 336 socket_interface_1_0_->Close(socket); |
| 337 pp::Module::Get()->core()->ReleaseResource(socket); |
| 338 |
| 339 PASS(); |
| 340 } |
| 341 |
| 342 std::string TestUDPSocket::TestSetOption_1_1() { |
| 343 PP_Resource socket = socket_interface_1_1_->Create(instance_->pp_instance()); |
| 344 ASSERT_NE(0, socket); |
| 345 |
| 346 // Multicast options are not supported in interface 1.1. |
| 347 ASSERT_EQ(PP_ERROR_BADARGUMENT, |
| 348 SetOptionValue(socket_interface_1_1_->SetOption, |
| 349 socket, |
| 350 PP_UDPSOCKET_OPTION_MULTICAST_LOOP, |
| 351 PP_MakeBool(PP_TRUE))); |
| 352 |
| 353 ASSERT_EQ(PP_ERROR_BADARGUMENT, |
| 354 SetOptionValue(socket_interface_1_1_->SetOption, |
| 355 socket, |
| 356 PP_UDPSOCKET_OPTION_MULTICAST_TTL, |
| 357 PP_MakeInt32(1))); |
| 358 |
| 359 socket_interface_1_1_->Close(socket); |
| 360 pp::Module::Get()->core()->ReleaseResource(socket); |
| 361 |
| 362 PASS(); |
| 363 } |
| 364 |
261 std::string TestUDPSocket::TestSetOption() { | 365 std::string TestUDPSocket::TestSetOption() { |
262 pp::UDPSocket socket(instance_); | 366 pp::UDPSocket socket(instance_); |
263 | 367 |
264 ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&socket)); | 368 ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&socket)); |
| 369 ASSERT_SUBTEST_SUCCESS(SetMulticastOptions(&socket)); |
265 | 370 |
266 // Try to pass incorrect option value's type. | 371 // Try to pass incorrect option value's type. |
267 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); | 372 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
268 callback.WaitForResult(socket.SetOption( | 373 callback.WaitForResult(socket.SetOption( |
269 PP_UDPSOCKET_OPTION_ADDRESS_REUSE, pp::Var(1), callback.GetCallback())); | 374 PP_UDPSOCKET_OPTION_ADDRESS_REUSE, pp::Var(1), callback.GetCallback())); |
270 CHECK_CALLBACK_BEHAVIOR(callback); | 375 CHECK_CALLBACK_BEHAVIOR(callback); |
271 ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 376 ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
272 | 377 |
| 378 // Invalid multicast TTL values (less than 0 and greater than 255). |
| 379 callback.WaitForResult(socket.SetOption( |
| 380 PP_UDPSOCKET_OPTION_MULTICAST_TTL, pp::Var(-1), callback.GetCallback())); |
| 381 CHECK_CALLBACK_BEHAVIOR(callback); |
| 382 ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
| 383 |
| 384 callback.WaitForResult(socket.SetOption( |
| 385 PP_UDPSOCKET_OPTION_MULTICAST_TTL, pp::Var(256), callback.GetCallback())); |
| 386 CHECK_CALLBACK_BEHAVIOR(callback); |
| 387 ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
| 388 |
273 callback.WaitForResult(socket.SetOption( | 389 callback.WaitForResult(socket.SetOption( |
274 PP_UDPSOCKET_OPTION_BROADCAST, pp::Var(false), callback.GetCallback())); | 390 PP_UDPSOCKET_OPTION_BROADCAST, pp::Var(false), callback.GetCallback())); |
275 CHECK_CALLBACK_BEHAVIOR(callback); | 391 CHECK_CALLBACK_BEHAVIOR(callback); |
276 ASSERT_EQ(PP_OK, callback.result()); | 392 ASSERT_EQ(PP_OK, callback.result()); |
277 | 393 |
278 callback.WaitForResult(socket.SetOption( | 394 callback.WaitForResult(socket.SetOption( |
279 PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE, pp::Var(4096), | 395 PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE, pp::Var(4096), |
280 callback.GetCallback())); | 396 callback.GetCallback())); |
281 CHECK_CALLBACK_BEHAVIOR(callback); | 397 CHECK_CALLBACK_BEHAVIOR(callback); |
282 ASSERT_EQ(PP_OK, callback.result()); | 398 ASSERT_EQ(PP_OK, callback.result()); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 ASSERT_SUBTEST_SUCCESS( | 497 ASSERT_SUBTEST_SUCCESS( |
382 ReadSocket(&server_socket, &recvfrom_address, message.size(), &str)); | 498 ReadSocket(&server_socket, &recvfrom_address, message.size(), &str)); |
383 ASSERT_EQ(message, str); | 499 ASSERT_EQ(message, str); |
384 } | 500 } |
385 | 501 |
386 server_socket.Close(); | 502 server_socket.Close(); |
387 client_socket.Close(); | 503 client_socket.Close(); |
388 | 504 |
389 PASS(); | 505 PASS(); |
390 } | 506 } |
| 507 |
| 508 std::string TestUDPSocket::TestMulticast() { |
| 509 pp::UDPSocket server1(instance_), server2(instance_); |
| 510 |
| 511 ASSERT_SUBTEST_SUCCESS(SetMulticastOptions(&server1)); |
| 512 ASSERT_SUBTEST_SUCCESS(SetMulticastOptions(&server2)); |
| 513 |
| 514 server1.Close(); |
| 515 server2.Close(); |
| 516 |
| 517 PASS(); |
| 518 } |
OLD | NEW |