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

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 callback.WaitForResult(socket_.Create(
104 socket::SocketType_Dev(socket::SocketType_Dev::TCP),
105 Optional<socket::CreateOptions_Dev>(), callback.GetCallback()));
106 if (callback.result() != PP_OK)
107 return "Create(): failed.";
108 socket_id = callback.output().socket_id();
109 if (socket_id <= 0)
110 return "Create(): invalid socket ID.";
111 }
112
113 {
114 TestCompletionCallback callback(pp_instance());
115 PP_Var output = PP_MakeUndefined();
116 callback.WaitForResult(socket_interface_->Listen(
117 pp_instance(), Var(socket_id).pp_var(), Var(address_).pp_var(),
118 Var(port_).pp_var(), PP_MakeUndefined(), &output,
119 callback.GetCallback().pp_completion_callback()));
120 if (callback.result() != PP_OK)
121 return "Listen(): failed.";
122 Var output_var(PASS_REF, output);
123 if (output_var.AsInt() != 0)
124 return "Listen(): failed.";
125 }
126
127 int32_t client_socket_id = 0;
128 {
129 TestCompletionCallbackWithOutput<socket::CreateInfo_Dev>
130 callback(pp_instance());
131 callback.WaitForResult(socket_.Create(
132 socket::SocketType_Dev(socket::SocketType_Dev::TCP),
133 Optional<socket::CreateOptions_Dev>(), callback.GetCallback()));
134 if (callback.result() != PP_OK)
135 return "Create(): failed.";
136 client_socket_id = callback.output().socket_id();
137 if (client_socket_id <= 0)
138 return "Create(): invalid socket ID.";
139 }
140
141 {
142 TestCompletionCallback callback(pp_instance());
143 PP_Var output = PP_MakeUndefined();
144 callback.WaitForResult(socket_interface_->Connect(
145 pp_instance(), Var(client_socket_id).pp_var(), Var(address_).pp_var(),
146 Var(port_).pp_var(), &output,
147 callback.GetCallback().pp_completion_callback()));
148 if (callback.result() != PP_OK)
149 return "Connect(): failed.";
150 Var output_var(PASS_REF, output);
151 if (output_var.AsInt() != 0)
152 return "Connect(): failed.";
153 }
154
155 int32_t accepted_socket_id = 0;
156 {
157 TestCompletionCallbackWithOutput<socket::AcceptInfo_Dev>
158 callback(pp_instance());
159 callback.WaitForResult(socket_.Accept(socket_id, callback.GetCallback()));
160 if (callback.result() != PP_OK)
161 return "Accept(): failed.";
162 socket::AcceptInfo_Dev accept_info = callback.output();
163 if (accept_info.result_code() != 0 || !accept_info.socket_id().IsSet())
164 return "Accept(): failed.";
165 accepted_socket_id = *accept_info.socket_id();
166 }
167
168 size_t bytes_written = 0;
169 {
170 TestCompletionCallbackWithOutput<socket::WriteInfo_Dev>
171 callback(pp_instance());
172 VarArrayBuffer array_buffer = ConvertToArrayBuffer(kSendContents);
173 callback.WaitForResult(socket_.Write(client_socket_id, array_buffer,
174 callback.GetCallback()));
175 if (callback.result() != PP_OK)
176 return "Write(): failed.";
177 socket::WriteInfo_Dev write_info = callback.output();
178 bytes_written = static_cast<size_t>(write_info.bytes_written());
179 if (bytes_written <= 0)
180 return "Write(): did not write any bytes.";
181 }
182
183 {
184 TestCompletionCallbackWithOutput<socket::ReadInfo_Dev>
185 callback(pp_instance());
186 callback.WaitForResult(socket_.Read(
187 accepted_socket_id, Optional<int32_t>(), callback.GetCallback()));
188 if (callback.result() != PP_OK)
189 return "Read(): failed.";
190
191 std::string data_string = ConvertFromArrayBuffer(
192 &callback.output().data());
193 if (data_string.compare(0, std::string::npos, kSendContents,
194 bytes_written) != 0) {
195 return "Read(): Received data does not match.";
196 }
197 }
198
199 socket_.Destroy(client_socket_id);
200 socket_.Destroy(accepted_socket_id);
201 socket_.Destroy(socket_id);
202 return std::string();
203 }
204
205 std::string TestClientSocket() {
206 socket::SocketType_Dev socket_type;
207 if (!socket_type.Populate(Var(test_type_).pp_var()))
208 return "Invalid socket type.";
209
210 int32_t socket_id = 0;
211 {
212 TestCompletionCallbackWithOutput<socket::CreateInfo_Dev>
213 callback(pp_instance());
214 callback.WaitForResult(socket_.Create(
215 socket_type, Optional<socket::CreateOptions_Dev>(),
216 callback.GetCallback()));
217 if (callback.result() != PP_OK)
218 return "Create(): failed.";
219 socket_id = callback.output().socket_id();
220 if (socket_id <= 0)
221 return "Create(): invalid socket ID.";
222 }
223
224 {
225 TestCompletionCallbackWithOutput<socket::SocketInfo_Dev>
226 callback(pp_instance());
227 callback.WaitForResult(socket_.GetInfo(socket_id,
228 callback.GetCallback()));
229 if (callback.result() != PP_OK)
230 return "GetInfo(): failed.";
231
232 socket::SocketInfo_Dev socket_info = callback.output();
233 if (socket_info.socket_type().value != socket_type.value)
234 return "GetInfo(): inconsistent socket type.";
235 if (socket_info.connected())
236 return "GetInfo(): socket should not be connected.";
237 if (socket_info.peer_address().IsSet() || socket_info.peer_port().IsSet())
238 return "GetInfo(): unconnected socket should not have peer.";
239 if (socket_info.local_address().IsSet() ||
240 socket_info.local_port().IsSet()) {
241 return "GetInfo(): unconnected socket should not have local binding.";
242 }
243 }
244
245 {
246 if (socket_type.value == socket::SocketType_Dev::TCP) {
247 TestCompletionCallback callback(pp_instance());
248 PP_Var output = PP_MakeUndefined();
249 callback.WaitForResult(socket_interface_->Connect(
250 pp_instance(), Var(socket_id).pp_var(), Var(address_).pp_var(),
251 Var(port_).pp_var(), &output,
252 callback.GetCallback().pp_completion_callback()));
253 if (callback.result() != PP_OK)
254 return "Connect(): failed.";
255 Var output_var(PASS_REF, output);
256 if (output_var.AsInt() != 0)
257 return "Connect(): failed.";
258 } else {
259 TestCompletionCallback callback(pp_instance());
260 PP_Var output = PP_MakeUndefined();
261 callback.WaitForResult(socket_interface_->Bind(
262 pp_instance(), Var(socket_id).pp_var(), Var("0.0.0.0").pp_var(),
263 Var(0).pp_var(), &output,
264 callback.GetCallback().pp_completion_callback()));
265 if (callback.result() != PP_OK)
266 return "Bind(): failed.";
267 Var output_var(PASS_REF, output);
268 if (output_var.AsInt() != 0)
269 return "Bind(): failed.";
270 }
271 }
272
273 {
274 TestCompletionCallbackWithOutput<socket::SocketInfo_Dev>
275 callback(pp_instance());
276 callback.WaitForResult(socket_.GetInfo(socket_id,
277 callback.GetCallback()));
278 if (callback.result() != PP_OK)
279 return "GetInfo(): failed.";
280
281 socket::SocketInfo_Dev socket_info = callback.output();
282 if (socket_info.socket_type().value != socket_type.value)
283 return "GetInfo(): inconsistent socket type.";
284 if (!socket_info.local_address().IsSet() ||
285 !socket_info.local_port().IsSet()) {
286 return "GetInfo(): bound socket should have local address and port.";
287 }
288 if (socket_type.value == socket::SocketType_Dev::TCP) {
289 if (!socket_info.connected())
290 return "GetInfo(): TCP socket should be connected.";
291 if (!socket_info.peer_address().IsSet() ||
292 !socket_info.peer_port().IsSet()) {
293 return "GetInfo(): connected TCP socket should have peer address and "
294 "port";
295 }
296 if (*socket_info.peer_address() != "127.0.0.1" ||
297 *socket_info.peer_port() != port_) {
298 return "GetInfo(): peer address and port should match the listening "
299 "server.";
300 }
301 } else {
302 if (socket_info.connected())
303 return "GetInfo(): UDP socket should not be connected.";
304 if (socket_info.peer_address().IsSet() ||
305 socket_info.peer_port().IsSet()) {
306 return "GetInfo(): unconnected UDP socket should not have peer "
307 "address or port.";
308 }
309 }
310 }
311
312 {
313 TestCompletionCallback callback(pp_instance());
314 PP_Var output = PP_MakeUndefined();
315 callback.WaitForResult(socket_interface_->SetNoDelay(
316 pp_instance(), Var(socket_id).pp_var(), Var(true).pp_var(),
317 &output, callback.GetCallback().pp_completion_callback()));
318 if (callback.result() != PP_OK)
319 return "SetNoDelay(): failed.";
320 Var output_var(PASS_REF, output);
321 if (socket_type.value == socket::SocketType_Dev::TCP) {
322 if (!output_var.AsBool())
323 return "SetNoDelay(): failed for TCP.";
324 } else {
325 if (output_var.AsBool())
326 return "SetNoDelay(): did not fail for UDP.";
327 }
328 }
329
330 {
331 TestCompletionCallback callback(pp_instance());
332 PP_Var output = PP_MakeUndefined();
333 callback.WaitForResult(socket_interface_->SetKeepAlive(
334 pp_instance(), Var(socket_id).pp_var(), Var(true).pp_var(),
335 Var(1000).pp_var(), &output,
336 callback.GetCallback().pp_completion_callback()));
337 if (callback.result() != PP_OK)
338 return "SetKeepAlive(): failed.";
339 Var output_var(PASS_REF, output);
340 if (socket_type.value == socket::SocketType_Dev::TCP) {
341 if (!output_var.AsBool())
342 return "SetKeepAlive(): failed for TCP.";
343 } else {
344 if (output_var.AsBool())
345 return "SetKeepAlive(): did not fail for UDP.";
346 }
347 }
348
349 {
350 VarArrayBuffer input_array_buffer = ConvertToArrayBuffer(kSendContents);
351 size_t bytes_written = 0;
352 int32_t result_code = 0;
353 VarArrayBuffer data;
354 if (socket_type.value == socket::SocketType_Dev::TCP) {
355 TestCompletionCallbackWithOutput<socket::ReadInfo_Dev>
356 read_callback(pp_instance());
357 int32_t read_result = socket_.Read(socket_id, Optional<int32_t>(),
358 read_callback.GetCallback());
359 if (read_result != PP_OK_COMPLETIONPENDING)
360 return "Read(): did not wait for data.";
361
362 TestCompletionCallbackWithOutput<socket::WriteInfo_Dev>
363 write_callback(pp_instance());
364 write_callback.WaitForResult(socket_.Write(
365 socket_id, input_array_buffer, write_callback.GetCallback()));
366 if (write_callback.result() != PP_OK)
367 return "Write(): failed.";
368 bytes_written = static_cast<size_t>(
369 write_callback.output().bytes_written());
370
371 read_callback.WaitForResult(read_result);
372 if (read_callback.result() != PP_OK)
373 return "Read(): failed.";
374 socket::ReadInfo_Dev read_info = read_callback.output();
375 result_code = read_info.result_code(),
376 data = read_info.data();
377 } else {
378 TestCompletionCallbackWithOutput<socket::RecvFromInfo_Dev>
379 recv_from_callback(pp_instance());
380 int32_t recv_from_result = socket_.RecvFrom(
381 socket_id, Optional<int32_t>(), recv_from_callback.GetCallback());
382 if (recv_from_result != PP_OK_COMPLETIONPENDING)
383 return "RecvFrom(): did not wait for data.";
384
385 TestCompletionCallbackWithOutput<socket::WriteInfo_Dev>
386 send_to_callback(pp_instance());
387 send_to_callback.WaitForResult(socket_.SendTo(
388 socket_id, input_array_buffer, address_, port_,
389 send_to_callback.GetCallback()));
390 if (send_to_callback.result() != PP_OK)
391 return "SendTo(): failed.";
392 bytes_written = static_cast<size_t>(
393 send_to_callback.output().bytes_written());
394
395 recv_from_callback.WaitForResult(recv_from_result);
396 if (recv_from_callback.result() != PP_OK)
397 return "RecvFrom(): failed.";
398 socket::RecvFromInfo_Dev recv_from_info = recv_from_callback.output();
399 result_code = recv_from_info.result_code();
400 data = recv_from_info.data();
401 }
402
403 if (bytes_written != strlen(kSendContents))
404 return "SendTo() or Write(): did not send the whole data buffer.";
405
406 if (result_code > 0 &&
407 static_cast<uint32_t>(result_code) != data.ByteLength()) {
408 return "Read() or RecvFrom(): inconsistent result code and byte "
409 "length.";
410 }
411
412 std::string output_string = ConvertFromArrayBuffer(&data);
413 size_t prefix_len = strlen(kReceiveContentsPrefix);
414 if (output_string.size() != prefix_len + kReceiveContentsSuffixSize ||
415 output_string.compare(0, prefix_len, kReceiveContentsPrefix) != 0) {
416 return std::string("Read() or RecvFrom(): mismatch data: ").append(
417 output_string);
418 }
419 }
420
421 socket_.Destroy(socket_id);
422 return std::string();
423 }
424
425 void Log(PP_LogLevel level, const char* format, ...) {
426 va_list args;
427 va_start(args, format);
428 char buf[512];
429 vsnprintf(buf, sizeof(buf) - 1, format, args);
430 buf[sizeof(buf) - 1] = '\0';
431 va_end(args);
432
433 Var value(buf);
434 console_interface_->Log(pp_instance(), level, value.pp_var());
435 }
436
437 void NotifyTestDone(const std::string& message) {
438 PostMessage(message);
439 }
440
441 VarArrayBuffer ConvertToArrayBuffer(const std::string data) {
442 VarArrayBuffer array_buffer(data.size());
443 memcpy(array_buffer.Map(), data.c_str(), data.size());
444 array_buffer.Unmap();
445 return array_buffer;
446 }
447
448 std::string ConvertFromArrayBuffer(VarArrayBuffer* array_buffer) {
449 std::string result(static_cast<const char*>(array_buffer->Map()),
450 array_buffer->ByteLength());
451 array_buffer->Unmap();
452 return result;
453 }
454
455 socket::Socket_Dev socket_;
456 const PPB_Console* console_interface_;
457 const PPB_Ext_Socket_Dev* socket_interface_;
458
459 std::string test_type_;
460 std::string address_;
461 int32_t port_;
462 };
463
464 class MyModule : public Module {
465 public:
466 MyModule() : Module() {}
467 virtual ~MyModule() {}
468
469 virtual Instance* CreateInstance(PP_Instance instance) {
470 return new MyInstance(instance);
471 }
472 };
473
474 namespace pp {
475
476 Module* CreateModule() {
477 return new MyModule();
478 }
479
480 } // namespace pp
481
OLDNEW
« no previous file with comments | « chrome/test/data/extensions/api_test/socket/ppapi/manifest.json ('k') | chrome/test/data/nacl/nacl_browser_test.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698