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

Side by Side Diff: native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc

Issue 26703008: [NaCl SDK] nacl_io: Add support for non-blocking connect/accept (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 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
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 <arpa/inet.h> 5 #include <arpa/inet.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <netinet/in.h> 8 #include <netinet/in.h>
9 #include <pthread.h> 9 #include <pthread.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 26 matching lines...) Expand all
37 namespace { 37 namespace {
38 38
39 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) { 39 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) {
40 memset(addr, 0, sizeof(*addr)); 40 memset(addr, 0, sizeof(*addr));
41 41
42 addr->sin_family = AF_INET; 42 addr->sin_family = AF_INET;
43 addr->sin_port = htons(port); 43 addr->sin_port = htons(port);
44 addr->sin_addr.s_addr = htonl(ip); 44 addr->sin_addr.s_addr = htonl(ip);
45 } 45 }
46 46
47 void SetNonBlocking(int sock) {
48 int flags = fcntl(sock, F_GETFL);
49 ASSERT_NE(-1, flags);
50 flags |= O_NONBLOCK;
51 ASSERT_EQ(0, fcntl(sock, F_SETFL, flags));
52 ASSERT_EQ(flags, fcntl(sock, F_GETFL));
53 }
54
47 class SocketTest : public ::testing::Test { 55 class SocketTest : public ::testing::Test {
48 public: 56 public:
49 SocketTest() : sock1(-1), sock2(-1) {} 57 SocketTest() : sock1(-1), sock2(-1) {}
50 58
51 void TearDown() { 59 void TearDown() {
52 if (sock1 != -1) 60 if (sock1 != -1)
53 EXPECT_EQ(0, close(sock1)); 61 EXPECT_EQ(0, close(sock1));
54 if (sock2 != -1) 62 if (sock2 != -1)
55 EXPECT_EQ(0, close(sock2)); 63 EXPECT_EQ(0, close(sock2));
56 } 64 }
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf))); 292 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf)));
285 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); 293 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
286 294
287 strcpy(outbuf, "world"); 295 strcpy(outbuf, "world");
288 memset(inbuf, 0, sizeof(inbuf)); 296 memset(inbuf, 0, sizeof(inbuf));
289 ASSERT_EQ(sizeof(outbuf), write(sock_, outbuf, sizeof(outbuf))); 297 ASSERT_EQ(sizeof(outbuf), write(sock_, outbuf, sizeof(outbuf)));
290 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf))); 298 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf)));
291 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); 299 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
292 } 300 }
293 301
302 TEST_F(SocketTestWithServer, TCPConnectNonBlock) {
303 char outbuf[256];
304 //char inbuf[512];
305
306 memset(outbuf, 1, sizeof(outbuf));
307
308 sockaddr_in addr;
309 socklen_t addrlen = sizeof(addr);
310
311 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
312
313 SetNonBlocking(sock_);
314 ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
315 ASSERT_EQ(EINPROGRESS, errno)
316 << "expected EINPROGRESS but got: " << strerror(errno) << "\n";
317 ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
318 ASSERT_EQ(EALREADY, errno);
319
320 // Wait for the socket connection to complete using poll()
321 struct pollfd pollfd = { sock_, POLLIN|POLLOUT, 0 };
322 ASSERT_EQ(1, poll(&pollfd, 1, -1));
323 ASSERT_EQ(POLLOUT, pollfd.revents);
324
325 // Attempts to connect again should yield EISCONN
326 ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
327 ASSERT_EQ(EISCONN, errno);
328
329 // And SO_ERROR should be 0.
330 }
331
294 TEST_F(SocketTest, Getsockopt) { 332 TEST_F(SocketTest, Getsockopt) {
295 sock1 = socket(AF_INET, SOCK_STREAM, 0); 333 sock1 = socket(AF_INET, SOCK_STREAM, 0);
296 EXPECT_GT(sock1, -1); 334 EXPECT_GT(sock1, -1);
297 int socket_error = 99; 335 int socket_error = 99;
298 socklen_t len = sizeof(socket_error); 336 socklen_t len = sizeof(socket_error);
299 337
300 // Test for valid option (SO_ERROR) which should be 0 when a socket 338 // Test for valid option (SO_ERROR) which should be 0 when a socket
301 // is first created. 339 // is first created.
302 ASSERT_EQ(0, getsockopt(sock1, SOL_SOCKET, SO_ERROR, &socket_error, &len)); 340 ASSERT_EQ(0, getsockopt(sock1, SOL_SOCKET, SO_ERROR, &socket_error, &len));
303 ASSERT_EQ(0, socket_error); 341 ASSERT_EQ(0, socket_error);
(...skipping 23 matching lines...) Expand all
327 len = sizeof(reuse); 365 len = sizeof(reuse);
328 ASSERT_EQ(0, setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &reuse, len)); 366 ASSERT_EQ(0, setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &reuse, len));
329 } 367 }
330 368
331 TEST_F(SocketTestUDP, Listen) { 369 TEST_F(SocketTestUDP, Listen) {
332 EXPECT_EQ(-1, listen(sock1, 10)); 370 EXPECT_EQ(-1, listen(sock1, 10));
333 EXPECT_EQ(errno, ENOTSUP); 371 EXPECT_EQ(errno, ENOTSUP);
334 } 372 }
335 373
336 TEST_F(SocketTestTCP, Listen) { 374 TEST_F(SocketTestTCP, Listen) {
337 // Accept should fail when socket not listening
338 sockaddr_in addr; 375 sockaddr_in addr;
339 socklen_t addrlen = sizeof(addr); 376 socklen_t addrlen = sizeof(addr);
340 377
341 int server_sock = sock1; 378 int server_sock = sock1;
342 379
343 // Accept before listen should fail 380 // Accept before listen should fail
344 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen)); 381 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
345 382
346 // Listen should fail on unbound socket 383 // Listen should fail on unbound socket
347 ASSERT_EQ(-1, listen(server_sock, 10)); 384 ASSERT_EQ(-1, listen(server_sock, 10));
348 385
349 // bind and listen 386 // Bind and Listen
350 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1)); 387 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
351 ASSERT_EQ(0, listen(server_sock, 10)) 388 ASSERT_EQ(0, listen(server_sock, 10))
352 << "listen failed with: " << strerror(errno); 389 << "listen failed with: " << strerror(errno);
353 390
354 // Connect to listening socket 391 // Connect to listening socket
355 int client_sock = sock2; 392 int client_sock = sock2;
356 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr); 393 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
357 addrlen = sizeof(addr); 394 addrlen = sizeof(addr);
358 ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen)) 395 ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
359 << "Failed with " << errno << ": " << strerror(errno) << "\n"; 396 << "Failed with " << errno << ": " << strerror(errno) << "\n";
(...skipping 10 matching lines...) Expand all
370 // Verify addr and addrlen were set correctly 407 // Verify addr and addrlen were set correctly
371 ASSERT_EQ(addrlen, sizeof(sockaddr_in)); 408 ASSERT_EQ(addrlen, sizeof(sockaddr_in));
372 sockaddr_in client_addr; 409 sockaddr_in client_addr;
373 ASSERT_EQ(0, getsockname(client_sock, (sockaddr*)&client_addr, &addrlen)); 410 ASSERT_EQ(0, getsockname(client_sock, (sockaddr*)&client_addr, &addrlen));
374 ASSERT_EQ(client_addr.sin_family, addr.sin_family); 411 ASSERT_EQ(client_addr.sin_family, addr.sin_family);
375 ASSERT_EQ(client_addr.sin_port, addr.sin_port); 412 ASSERT_EQ(client_addr.sin_port, addr.sin_port);
376 ASSERT_EQ(client_addr.sin_addr.s_addr, addr.sin_addr.s_addr); 413 ASSERT_EQ(client_addr.sin_addr.s_addr, addr.sin_addr.s_addr);
377 414
378 char inbuf[512]; 415 char inbuf[512];
379 ASSERT_EQ(5, recv(new_socket, inbuf, 5, 0)); 416 ASSERT_EQ(5, recv(new_socket, inbuf, 5, 0));
417 ASSERT_EQ(0, close(new_socket));
418 }
419
420 TEST_F(SocketTestTCP, ListenNonBlocking) {
421 int server_sock = sock1;
422
423 // Set non-blocking
424 SetNonBlocking(server_sock);
425
426 // bind and listen
427 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
428 ASSERT_EQ(0, listen(server_sock, 10))
429 << "listen failed with: " << strerror(errno);
430
431 // Accept should fail with EAGAIN since there is no incomming
432 // connection.
433 sockaddr_in addr;
434 socklen_t addrlen = sizeof(addr);
435 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
436 ASSERT_EQ(EAGAIN, errno);
437
438 // If we poll the listening socket it should also return
439 // not readable to indicate that no connections are available
440 // to accept.
441 struct pollfd pollfd = { server_sock, POLLIN|POLLOUT, 0 };
442 ASSERT_EQ(0, poll(&pollfd, 1, 0));
443
444 // Connect to listening socket
445 int client_sock = sock2;
446 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
447 addrlen = sizeof(addr);
448 ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
449 << "Failed with " << errno << ": " << strerror(errno) << "\n";
450
451 // Not poll again but with an infintie timeout.
452 pollfd.fd = server_sock;
453 pollfd.events = POLLIN | POLLOUT;
454 ASSERT_EQ(1, poll(&pollfd, 1, -1));
455
456 // Now non-blocking accept should return the new socket
457 int new_socket = accept(server_sock, (sockaddr*)&addr, &addrlen);
458 ASSERT_NE(-1, new_socket)
459 << "accept failed with: " << strerror(errno) << "\n";
460 ASSERT_EQ(0, close(new_socket));
461
462 // Accept calls should once again fail with EAGAIN
463 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
464 ASSERT_EQ(EAGAIN, errno);
465
466 // As should polling the listening socket
467 pollfd.fd = server_sock;
468 pollfd.events = POLLIN | POLLOUT;
469 ASSERT_EQ(0, poll(&pollfd, 1, 0));
380 } 470 }
381 471
382 #endif // PROVIDES_SOCKET_API 472 #endif // PROVIDES_SOCKET_API
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698