Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: chrome/test/data/extensions/api_test/socket/ppapi/test_socket.cc

Issue 13811036: Add Pepper API tests for chrome.socket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 <cstdarg>
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstring>
9
10 #include "ppapi/c/ppb_console.h"
11 #include "ppapi/cpp/extensions/dev/socket_dev.h"
12 #include "ppapi/cpp/instance.h"
13 #include "ppapi/cpp/module.h"
14 #include "ppapi/cpp/var.h"
15 #include "ppapi/cpp/var_array_buffer.h"
16 #include "ppapi/tests/test_utils.h"
17
18 using namespace pp;
19 using namespace pp::ext;
20
21 namespace {
22
23 const char* const kSendContents = "0100000005320000005hello";
24 const char* const kReceiveContentsPrefix = "0100000005320000005";
25 const size_t kReceiveContentsSuffixSize = 11;
26
27 } // namespace
28
29 class MyInstance : public Instance {
30 public:
31 explicit MyInstance(PP_Instance instance)
32 : Instance(instance),
33 socket_(InstanceHandle(instance)),
34 console_interface_(NULL),
35 socket_interface_(NULL),
36 port_(0) {
37 }
38 virtual ~MyInstance() {
39 }
40
41 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
42 console_interface_ = static_cast<const PPB_Console*>(
43 Module::Get()->GetBrowserInterface(PPB_CONSOLE_INTERFACE));
44
45 // TODO(yzshen): Remove this one once the cpp wrapper supports all socket
46 // functions.
47 socket_interface_ = static_cast<const PPB_Ext_Socket_Dev*>(
48 Module::Get()->GetBrowserInterface(PPB_EXT_SOCKET_DEV_INTERFACE));
49 if (!console_interface_ || !socket_interface_)
50 return false;
51
52 PostMessage(Var("ready"));
53 return true;
54 }
55
56 virtual void HandleMessage(const pp::Var& message_data) {
57 std::string output;
58 do {
59 if (!message_data.is_string()) {
60 output = "Invalid control message.";
61 break;
62 }
63
64 std::string control_message = message_data.AsString();
65 std::vector<std::string> parts;
66 size_t pos = 0;
67 size_t next_match = 0;
68 while (pos < control_message.size()) {
69 next_match = control_message.find(':', pos);
70 if (next_match == std::string::npos)
71 next_match = control_message.size();
72 parts.push_back(control_message.substr(pos, next_match - pos));
73 pos = next_match + 1;
74 }
75
76 if (parts.size() != 3) {
77 output = "Invalid protocol/address/port input.";
78 break;
79 }
80
81 test_type_ = parts[0];
82 address_ = parts[1];
83 port_ = atoi(parts[2].c_str());
84 Log(PP_LOGLEVEL_LOG, "Running tests, protocol %s, server %s:%d",
85 test_type_.c_str(), address_.c_str(), port_);
86
87 if (test_type_ == "tcp_server") {
88 output = TestServerSocket();
89 } else {
90 output = TestClientSocket();
91 }
92 } while (false);
93
94 NotifyTestDone(output);
95 }
96
97 private:
98 std::string TestServerSocket() {
99 int32_t socket_id = 0;
100 {
101 TestCompletionCallbackWithOutput<socket::CreateInfo_Dev>
102 callback(pp_instance());
103 int32_t result = socket_.Create(
104 socket::SocketType_Dev(socket::SocketType_Dev::TCP),
105 Optional<socket::CreateOptions_Dev>(), callback.GetCallback());
106 if (result == PP_OK_COMPLETIONPENDING)
107 result = callback.WaitForResult();
108 if (result != PP_OK)
109 return "Create(): failed.";
110 socket_id = callback.output().socket_id();
111 if (socket_id <= 0)
112 return "Create(): invalid socket ID.";
113 }
114
115 {
116 TestCompletionCallback callback(pp_instance());
117 PP_Var output = PP_MakeUndefined();
118 int32_t result = socket_interface_->Listen(
119 pp_instance(), Var(socket_id).pp_var(), Var(address_).pp_var(),
120 Var(port_).pp_var(), PP_MakeUndefined(), &output,
121 callback.GetCallback().pp_completion_callback());
122 if (result == PP_OK_COMPLETIONPENDING)
123 result = callback.WaitForResult();
124 if (result != PP_OK)
125 return "Listen(): failed.";
126 Var output_var(PASS_REF, output);
127 if (output_var.AsInt() != 0)
128 return "Listen(): failed.";
129 }
130
131 int32_t client_socket_id = 0;
132 {
133 TestCompletionCallbackWithOutput<socket::CreateInfo_Dev>
134 callback(pp_instance());
135 int32_t result = socket_.Create(
136 socket::SocketType_Dev(socket::SocketType_Dev::TCP),
137 Optional<socket::CreateOptions_Dev>(), callback.GetCallback());
138 if (result == PP_OK_COMPLETIONPENDING)
139 result = callback.WaitForResult();
140 if (result != PP_OK)
141 return "Create(): failed.";
142 client_socket_id = callback.output().socket_id();
143 if (client_socket_id <= 0)
144 return "Create(): invalid socket ID.";
145 }
146
147 {
148 TestCompletionCallback callback(pp_instance());
149 PP_Var output = PP_MakeUndefined();
150 int32_t result = socket_interface_->Connect(
151 pp_instance(), Var(client_socket_id).pp_var(), Var(address_).pp_var(),
152 Var(port_).pp_var(), &output,
153 callback.GetCallback().pp_completion_callback());
154 if (result == PP_OK_COMPLETIONPENDING)
155 result = callback.WaitForResult();
156 if (result != PP_OK)
157 return "Connect(): failed.";
158 Var output_var(PASS_REF, output);
159 if (output_var.AsInt() != 0)
160 return "Connect(): failed.";
161 }
162
163 int32_t accepted_socket_id = 0;
164 {
165 TestCompletionCallbackWithOutput<socket::AcceptInfo_Dev>
166 callback(pp_instance());
167 int32_t result = socket_.Accept(socket_id, callback.GetCallback());
168 if (result == PP_OK_COMPLETIONPENDING)
169 result = callback.WaitForResult();
170 socket::AcceptInfo_Dev accept_info = callback.output();
171 if (accept_info.result_code() != 0 || !accept_info.socket_id().IsSet())
172 return "Accept(): failed.";
173 accepted_socket_id = *accept_info.socket_id();
174 }
175
176 size_t bytes_written = 0;
177 {
178 TestCompletionCallbackWithOutput<socket::WriteInfo_Dev>
179 callback(pp_instance());
180 VarArrayBuffer array_buffer = ConvertToArrayBuffer(kSendContents);
181 int32_t result = socket_.Write(client_socket_id, array_buffer,
182 callback.GetCallback());
183 if (result == PP_OK_COMPLETIONPENDING)
184 result = callback.WaitForResult();
185 if (result != PP_OK)
186 return "Write(): failed.";
187 socket::WriteInfo_Dev write_info = callback.output();
188 bytes_written = static_cast<size_t>(write_info.bytes_written());
189 if (bytes_written <= 0)
190 return "Write(): did not write any bytes.";
191 }
192
193 {
194 TestCompletionCallbackWithOutput<socket::ReadInfo_Dev>
195 callback(pp_instance());
196 int32_t result = socket_.Read(accepted_socket_id, Optional<int32_t>(),
197 callback.GetCallback());
198 if (result == PP_OK_COMPLETIONPENDING)
199 result = callback.WaitForResult();
200 if (result != PP_OK)
201 return "Read(): failed.";
202
203 VarArrayBuffer array_buffer(callback.output().data());
204 std::string data_string = ConvertFromArrayBuffer(&array_buffer);
205 if (data_string.compare(0, std::string::npos, kSendContents,
206 bytes_written) != 0) {
207 return "Read(): Received data does not match.";
208 }
209 }
210
211 socket_.Destroy(client_socket_id);
212 socket_.Destroy(accepted_socket_id);
213 socket_.Destroy(socket_id);
214 return std::string();
215 }
216
217 std::string TestClientSocket() {
218 socket::SocketType_Dev socket_type;
219 if (!socket_type.Populate(Var(test_type_).pp_var()))
220 return "Invalid socket type.";
221
222 int32_t socket_id = 0;
223 {
224 TestCompletionCallbackWithOutput<socket::CreateInfo_Dev>
225 callback(pp_instance());
226 int32_t result = socket_.Create(socket_type,
227 Optional<socket::CreateOptions_Dev>(),
228 callback.GetCallback());
229 if (result == PP_OK_COMPLETIONPENDING)
230 result = callback.WaitForResult();
231 if (result != PP_OK)
232 return "Create(): failed.";
233 socket_id = callback.output().socket_id();
234 if (socket_id <= 0)
235 return "Create(): invalid socket ID.";
236 }
237
238 {
239 TestCompletionCallbackWithOutput<socket::SocketInfo_Dev>
240 callback(pp_instance());
241 int32_t result = socket_.GetInfo(socket_id, callback.GetCallback());
242 if (result == PP_OK_COMPLETIONPENDING)
243 result = callback.WaitForResult();
244 if (result != PP_OK)
245 return "GetInfo(): failed.";
246
247 socket::SocketInfo_Dev socket_info = callback.output();
248 if (socket_info.socket_type().value != socket_type.value)
249 return "GetInfo(): inconsistent socket type.";
250 if (socket_info.connected())
251 return "GetInfo(): socket should not be connected.";
252 if (socket_info.peer_address().IsSet() || socket_info.peer_port().IsSet())
253 return "GetInfo(): unconnected socket should not have peer.";
254 if (socket_info.local_address().IsSet() ||
255 socket_info.local_port().IsSet()) {
256 return "GetInfo(): unconnected socket should not have local binding.";
257 }
258 }
259
260 {
261 if (socket_type.value == socket::SocketType_Dev::TCP) {
262 TestCompletionCallback callback(pp_instance());
263 PP_Var output = PP_MakeUndefined();
264 int32_t result = socket_interface_->Connect(
265 pp_instance(), Var(socket_id).pp_var(), Var(address_).pp_var(),
266 Var(port_).pp_var(), &output,
267 callback.GetCallback().pp_completion_callback());
268 if (result == PP_OK_COMPLETIONPENDING)
269 result = callback.WaitForResult();
270 if (result != PP_OK)
271 return "Connect(): failed.";
272 Var output_var(PASS_REF, output);
273 if (output_var.AsInt() != 0)
274 return "Connect(): failed.";
275 } else {
276 TestCompletionCallback callback(pp_instance());
277 PP_Var output = PP_MakeUndefined();
278 int32_t result = socket_interface_->Bind(
279 pp_instance(), Var(socket_id).pp_var(), Var("0.0.0.0").pp_var(),
280 Var(0).pp_var(), &output,
281 callback.GetCallback().pp_completion_callback());
282 if (result == PP_OK_COMPLETIONPENDING)
283 result = callback.WaitForResult();
284 if (result != PP_OK)
285 return "Bind(): failed.";
286 Var output_var(PASS_REF, output);
287 if (output_var.AsInt() != 0)
288 return "Bind(): failed.";
289 }
290 }
291
292 {
293 TestCompletionCallbackWithOutput<socket::SocketInfo_Dev>
294 callback(pp_instance());
295 int32_t result = socket_.GetInfo(socket_id, callback.GetCallback());
296 if (result == PP_OK_COMPLETIONPENDING)
297 result = callback.WaitForResult();
298 if (result != PP_OK)
299 return "GetInfo(): failed.";
300
301 socket::SocketInfo_Dev socket_info = callback.output();
302 if (socket_info.socket_type().value != socket_type.value)
303 return "GetInfo(): inconsistent socket type.";
304 if (!socket_info.local_address().IsSet() ||
305 !socket_info.local_port().IsSet()) {
306 return "GetInfo(): bound socket should have local address and port.";
307 }
308 if (socket_type.value == socket::SocketType_Dev::TCP) {
309 if (!socket_info.connected())
310 return "GetInfo(): TCP socket should be connected.";
311 if (!socket_info.peer_address().IsSet() ||
312 !socket_info.peer_port().IsSet()) {
313 return "GetInfo(): connected TCP socket should have peer address and "
314 "port";
315 }
316 if (*socket_info.peer_address() != "127.0.0.1" ||
317 *socket_info.peer_port() != port_) {
318 return "GetInfo(): peer address and port should match the listening "
319 "server.";
320 }
321 } else {
322 if (socket_info.connected())
323 return "GetInfo(): UDP socket should not be connected.";
324 if (socket_info.peer_address().IsSet() ||
325 socket_info.peer_port().IsSet()) {
326 return "GetInfo(): unconnected UDP socket should not have peer "
327 "address or port.";
328 }
329 }
330 }
331
332 {
333 TestCompletionCallback callback(pp_instance());
334 PP_Var output = PP_MakeUndefined();
335 int32_t result = socket_interface_->SetNoDelay(
336 pp_instance(), Var(socket_id).pp_var(), Var(true).pp_var(),
337 &output, callback.GetCallback().pp_completion_callback());
338 if (result == PP_OK_COMPLETIONPENDING)
339 result = callback.WaitForResult();
340 if (result != PP_OK)
341 return "SetNoDelay(): failed.";
342 Var output_var(PASS_REF, output);
343 if (socket_type.value == socket::SocketType_Dev::TCP) {
344 if (!output_var.AsBool())
345 return "SetNoDelay(): failed for TCP.";
346 } else {
347 if (output_var.AsBool())
348 return "SetNoDelay(): did not fail for UDP.";
349 }
350 }
351
352 {
353 TestCompletionCallback callback(pp_instance());
354 PP_Var output = PP_MakeUndefined();
355 int32_t result = socket_interface_->SetKeepAlive(
356 pp_instance(), Var(socket_id).pp_var(), Var(true).pp_var(),
357 Var(1000).pp_var(), &output,
358 callback.GetCallback().pp_completion_callback());
359 if (result == PP_OK_COMPLETIONPENDING)
360 result = callback.WaitForResult();
361 if (result != PP_OK)
362 return "SetKeepAlive(): failed.";
363 Var output_var(PASS_REF, output);
364 if (socket_type.value == socket::SocketType_Dev::TCP) {
365 if (!output_var.AsBool())
366 return "SetKeepAlive(): failed for TCP.";
367 } else {
368 if (output_var.AsBool())
369 return "SetKeepAlive(): did not fail for UDP.";
370 }
371 }
372
373 {
374 VarArrayBuffer input_array_buffer = ConvertToArrayBuffer(kSendContents);
375 size_t bytes_written = 0;
376 int32_t result_code = 0;
377 Var data;
378 if (socket_type.value == socket::SocketType_Dev::TCP) {
379 TestCompletionCallbackWithOutput<socket::ReadInfo_Dev>
380 read_callback(pp_instance());
381 int32_t result = socket_.Read(socket_id, Optional<int32_t>(),
382 read_callback.GetCallback());
383 if (result != PP_OK_COMPLETIONPENDING)
384 return "Read(): did not wait for data.";
385
386 TestCompletionCallbackWithOutput<socket::WriteInfo_Dev>
387 write_callback(pp_instance());
388 result = socket_.Write(socket_id, input_array_buffer,
389 write_callback.GetCallback());
390 if (result == PP_OK_COMPLETIONPENDING)
391 result = write_callback.WaitForResult();
392 if (result != PP_OK)
393 return "Write(): failed.";
394 bytes_written = static_cast<size_t>(
395 write_callback.output().bytes_written());
396
397 result = read_callback.WaitForResult();
398 if (result != PP_OK)
399 return "Read(): failed.";
400 socket::ReadInfo_Dev read_info = read_callback.output();
401 result_code = read_info.result_code(),
402 data = read_info.data();
403 } else {
404 TestCompletionCallbackWithOutput<socket::RecvFromInfo_Dev>
405 recv_from_callback(pp_instance());
406 int32_t result = socket_.RecvFrom(socket_id, Optional<int32_t>(),
407 recv_from_callback.GetCallback());
408 if (result != PP_OK_COMPLETIONPENDING)
409 return "RecvFrom(): did not wait for data.";
410
411 TestCompletionCallbackWithOutput<socket::WriteInfo_Dev>
412 send_to_callback(pp_instance());
413 result = socket_.SendTo(socket_id, input_array_buffer, address_, port_,
414 send_to_callback.GetCallback());
415 if (result == PP_OK_COMPLETIONPENDING)
416 result = send_to_callback.WaitForResult();
417 if (result != PP_OK)
418 return "SendTo(): failed.";
419 bytes_written = static_cast<size_t>(
420 send_to_callback.output().bytes_written());
421
422 result = recv_from_callback.WaitForResult();
423 if (result != PP_OK)
424 return "RecvFrom(): failed.";
425 socket::RecvFromInfo_Dev recv_from_info = recv_from_callback.output();
426 result_code = recv_from_info.result_code();
427 data = recv_from_info.data();
428 }
429
430 if (bytes_written != strlen(kSendContents))
431 return "SendTo() or Write(): did not send the whole data buffer.";
432
433 VarArrayBuffer output_array_buffer(data);
434 if (result_code > 0 &&
435 static_cast<uint32_t>(result_code) !=
436 output_array_buffer.ByteLength()) {
437 return "Read() or RecvFrom(): inconsistent result code and byte "
438 "length.";
439 }
440
441 std::string output_string = ConvertFromArrayBuffer(
442 &output_array_buffer);
443 size_t prefix_len = strlen(kReceiveContentsPrefix);
444 if (output_string.size() != prefix_len + kReceiveContentsSuffixSize ||
445 output_string.compare(0, prefix_len, kReceiveContentsPrefix) != 0) {
446 return std::string("Read() or RecvFrom(): mismatch data: ").append(
447 output_string);
448 }
449 }
450
451 socket_.Destroy(socket_id);
452 return std::string();
453 }
454
455 void Log(PP_LogLevel level, const char* format, ...) {
456 va_list args;
457 va_start(args, format);
458 char buf[512];
459 vsnprintf(buf, sizeof(buf) - 1, format, args);
460 buf[sizeof(buf) - 1] = '\0';
461 va_end(args);
462
463 Var value(buf);
464 console_interface_->Log(pp_instance(), level, value.pp_var());
465 }
466
467 void NotifyTestDone(const std::string& message) {
468 PostMessage(message);
469 }
470
471 VarArrayBuffer ConvertToArrayBuffer(const std::string data) {
472 VarArrayBuffer array_buffer(data.size());
473 memcpy(array_buffer.Map(), data.c_str(), data.size());
474 array_buffer.Unmap();
475 return array_buffer;
476 }
477
478 std::string ConvertFromArrayBuffer(VarArrayBuffer* array_buffer) {
479 std::string result(static_cast<const char*>(array_buffer->Map()),
480 array_buffer->ByteLength());
481 array_buffer->Unmap();
482 return result;
483 }
484
485 socket::Socket_Dev socket_;
486 const PPB_Console* console_interface_;
487 const PPB_Ext_Socket_Dev* socket_interface_;
488
489 std::string test_type_;
490 std::string address_;
491 int32_t port_;
492 };
493
494 class MyModule : public Module {
495 public:
496 MyModule() : Module() {}
497 virtual ~MyModule() {}
498
499 virtual Instance* CreateInstance(PP_Instance instance) {
500 return new MyInstance(instance);
501 }
502 };
503
504 namespace pp {
505
506 Module* CreateModule() {
507 return new MyModule();
508 }
509
510 } // namespace pp
511
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698