blob: 966dfe77f1326e5b5b0f3656b4f13b681d48d365 [file] [log] [blame]
David Pursell0eb8e1b2016-01-14 17:18:27 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// Tests socket functionality using loopback connections. Requires IPv4 and
18// IPv6 capabilities, and that kTestPort is available for loopback
19// communication. These tests also assume that no UDP packets are lost,
20// which should be the case for loopback communication, but is not guaranteed.
21
22#include <cutils/sockets.h>
23
David Pursell572bce22016-01-15 14:19:56 -080024#include <time.h>
25
David Pursell0eb8e1b2016-01-14 17:18:27 -080026#include <gtest/gtest.h>
27
28enum {
29 // This port must be available for loopback communication.
30 kTestPort = 54321
31};
32
33// Makes sure the passed sockets are valid, sends data between them, and closes
34// them. Any failures are logged with gtest.
35//
36// On Mac recvfrom() will not fill in the address for TCP sockets, so we need
37// separate logic paths depending on socket type.
38static void TestConnectedSockets(cutils_socket_t server, cutils_socket_t client,
39 int type) {
40 ASSERT_NE(INVALID_SOCKET, server);
41 ASSERT_NE(INVALID_SOCKET, client);
42
43 char buffer[3];
44 sockaddr_storage addr;
45 socklen_t addr_size = sizeof(addr);
46
47 // Send client -> server first to get the UDP client's address.
48 ASSERT_EQ(3, send(client, "foo", 3, 0));
49 if (type == SOCK_DGRAM) {
50 EXPECT_EQ(3, recvfrom(server, buffer, 3, 0,
51 reinterpret_cast<sockaddr*>(&addr), &addr_size));
52 } else {
53 EXPECT_EQ(3, recv(server, buffer, 3, 0));
54 }
55 EXPECT_EQ(0, memcmp(buffer, "foo", 3));
56
57 // Now send server -> client.
58 if (type == SOCK_DGRAM) {
59 ASSERT_EQ(3, sendto(server, "bar", 3, 0,
60 reinterpret_cast<sockaddr*>(&addr), addr_size));
61 } else {
62 ASSERT_EQ(3, send(server, "bar", 3, 0));
63 }
64 EXPECT_EQ(3, recv(client, buffer, 3, 0));
65 EXPECT_EQ(0, memcmp(buffer, "bar", 3));
66
67 EXPECT_EQ(0, socket_close(server));
68 EXPECT_EQ(0, socket_close(client));
69}
70
David Pursell572bce22016-01-15 14:19:56 -080071// Tests receive timeout. The timing verification logic must be very coarse to
72// make sure different systems can all pass these tests.
73void TestReceiveTimeout(cutils_socket_t sock) {
74 time_t start_time;
75 char buffer[32];
76
77 // Make sure a 20ms timeout completes in 1 second or less.
78 EXPECT_EQ(0, socket_set_receive_timeout(sock, 20));
79 start_time = time(nullptr);
80 EXPECT_EQ(-1, recv(sock, buffer, sizeof(buffer), 0));
81 EXPECT_LE(difftime(time(nullptr), start_time), 1.0);
82
83 // Make sure a 1250ms timeout takes 1 second or more.
84 EXPECT_EQ(0, socket_set_receive_timeout(sock, 1250));
85 start_time = time(nullptr);
86 EXPECT_EQ(-1, recv(sock, buffer, sizeof(buffer), 0));
87 EXPECT_LE(1.0, difftime(time(nullptr), start_time));
88}
89
David Pursell0eb8e1b2016-01-14 17:18:27 -080090// Tests socket_inaddr_any_server() and socket_network_client() for IPv4 UDP.
91TEST(SocketsTest, TestIpv4UdpLoopback) {
92 cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
93 cutils_socket_t client = socket_network_client("127.0.0.1", kTestPort,
94 SOCK_DGRAM);
95
96 TestConnectedSockets(server, client, SOCK_DGRAM);
97}
98
99// Tests socket_inaddr_any_server() and socket_network_client() for IPv4 TCP.
100TEST(SocketsTest, TestIpv4TcpLoopback) {
101 cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
102 ASSERT_NE(INVALID_SOCKET, server);
103
104 cutils_socket_t client = socket_network_client("127.0.0.1", kTestPort,
105 SOCK_STREAM);
106 cutils_socket_t handler = accept(server, nullptr, nullptr);
107 EXPECT_EQ(0, socket_close(server));
108
109 TestConnectedSockets(handler, client, SOCK_STREAM);
110}
111
112// Tests socket_inaddr_any_server() and socket_network_client() for IPv6 UDP.
113TEST(SocketsTest, TestIpv6UdpLoopback) {
114 cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
115 cutils_socket_t client = socket_network_client("::1", kTestPort,
116 SOCK_DGRAM);
117
118 TestConnectedSockets(server, client, SOCK_DGRAM);
119}
120
121// Tests socket_inaddr_any_server() and socket_network_client() for IPv6 TCP.
122TEST(SocketsTest, TestIpv6TcpLoopback) {
123 cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
124 ASSERT_NE(INVALID_SOCKET, server);
125
126 cutils_socket_t client = socket_network_client("::1", kTestPort,
127 SOCK_STREAM);
128 cutils_socket_t handler = accept(server, nullptr, nullptr);
129 EXPECT_EQ(0, socket_close(server));
130
131 TestConnectedSockets(handler, client, SOCK_STREAM);
132}
David Pursell572bce22016-01-15 14:19:56 -0800133
134// Tests setting a receive timeout for UDP sockets.
135TEST(SocketsTest, TestUdpReceiveTimeout) {
136 cutils_socket_t sock = socket_inaddr_any_server(kTestPort, SOCK_DGRAM);
137 ASSERT_NE(INVALID_SOCKET, sock);
138
139 TestReceiveTimeout(sock);
140
141 EXPECT_EQ(0, socket_close(sock));
142}
143
144// Tests setting a receive timeout for TCP sockets.
145TEST(SocketsTest, TestTcpReceiveTimeout) {
146 cutils_socket_t server = socket_inaddr_any_server(kTestPort, SOCK_STREAM);
147 ASSERT_NE(INVALID_SOCKET, server);
148
149 cutils_socket_t client = socket_network_client("localhost", kTestPort,
150 SOCK_STREAM);
151 cutils_socket_t handler = accept(server, nullptr, nullptr);
152 EXPECT_EQ(0, socket_close(server));
153
154 TestReceiveTimeout(handler);
155
156 EXPECT_EQ(0, socket_close(client));
157 EXPECT_EQ(0, socket_close(handler));
158}