blob: 1fd9d7c227890273a3864fb98b86105ce22a8e88 [file] [log] [blame]
David Pursell815c7be2015-12-09 17:09:54 -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
David Pursell572bce22016-01-15 14:19:56 -080017// Tests UDP functionality using loopback connections. Requires that kTestPort is available
David Pursell815c7be2015-12-09 17:09:54 -080018// for loopback communication on the host. These tests also assume that no UDP packets are lost,
19// which should be the case for loopback communication, but is not guaranteed.
20
21#include "socket.h"
22
David Pursell815c7be2015-12-09 17:09:54 -080023#include <gtest/gtest.h>
24
25enum {
26 // This port must be available for loopback communication.
David Pursell572bce22016-01-15 14:19:56 -080027 kTestPort = 54321,
David Pursell815c7be2015-12-09 17:09:54 -080028
29 // Don't wait forever in a unit test.
David Pursell572bce22016-01-15 14:19:56 -080030 kTestTimeoutMs = 3000,
David Pursell815c7be2015-12-09 17:09:54 -080031};
32
David Pursell572bce22016-01-15 14:19:56 -080033// Creates connected sockets |server| and |client|. Returns true on success.
34bool MakeConnectedSockets(Socket::Protocol protocol, std::unique_ptr<Socket>* server,
35 std::unique_ptr<Socket>* client, const std::string hostname = "localhost",
36 int port = kTestPort) {
37 *server = Socket::NewServer(protocol, port);
38 if (*server == nullptr) {
39 ADD_FAILURE() << "Failed to create server.";
40 return false;
David Pursell815c7be2015-12-09 17:09:54 -080041 }
42
David Pursell572bce22016-01-15 14:19:56 -080043 *client = Socket::NewClient(protocol, hostname, port, nullptr);
44 if (*client == nullptr) {
45 ADD_FAILURE() << "Failed to create client.";
46 return false;
David Pursell815c7be2015-12-09 17:09:54 -080047 }
48
David Pursell572bce22016-01-15 14:19:56 -080049 // TCP passes the client off to a new socket.
50 if (protocol == Socket::Protocol::kTcp) {
51 *server = (*server)->Accept();
52 if (*server == nullptr) {
53 ADD_FAILURE() << "Failed to accept client connection.";
54 return false;
55 }
David Pursell815c7be2015-12-09 17:09:54 -080056 }
57
David Pursell572bce22016-01-15 14:19:56 -080058 return true;
59}
David Pursell815c7be2015-12-09 17:09:54 -080060
David Pursell572bce22016-01-15 14:19:56 -080061// Sends a string over a Socket. Returns true if the full string (without terminating char)
David Pursell815c7be2015-12-09 17:09:54 -080062// was sent.
David Pursell572bce22016-01-15 14:19:56 -080063static bool SendString(Socket* sock, const std::string& message) {
64 return sock->Send(message.c_str(), message.length()) == static_cast<ssize_t>(message.length());
David Pursell815c7be2015-12-09 17:09:54 -080065}
66
David Pursell572bce22016-01-15 14:19:56 -080067// Receives a string from a Socket. Returns true if the full string (without terminating char)
68// was received.
69static bool ReceiveString(Socket* sock, const std::string& message) {
70 std::string received(message.length(), '\0');
71 ssize_t bytes = sock->ReceiveAll(&received[0], received.length(), kTestTimeoutMs);
72 return static_cast<size_t>(bytes) == received.length() && received == message;
David Pursell815c7be2015-12-09 17:09:54 -080073}
74
75// Tests sending packets client -> server, then server -> client.
David Pursell572bce22016-01-15 14:19:56 -080076TEST(SocketTest, TestSendAndReceive) {
77 std::unique_ptr<Socket> server, client;
David Pursell815c7be2015-12-09 17:09:54 -080078
David Pursell572bce22016-01-15 14:19:56 -080079 for (Socket::Protocol protocol : {Socket::Protocol::kUdp, Socket::Protocol::kTcp}) {
80 ASSERT_TRUE(MakeConnectedSockets(protocol, &server, &client));
David Pursell815c7be2015-12-09 17:09:54 -080081
David Pursell572bce22016-01-15 14:19:56 -080082 EXPECT_TRUE(SendString(client.get(), "foo"));
83 EXPECT_TRUE(ReceiveString(server.get(), "foo"));
84
85 EXPECT_TRUE(SendString(server.get(), "bar baz"));
86 EXPECT_TRUE(ReceiveString(client.get(), "bar baz"));
87 }
David Pursell815c7be2015-12-09 17:09:54 -080088}
89
90// Tests sending and receiving large packets.
David Pursell572bce22016-01-15 14:19:56 -080091TEST(SocketTest, TestLargePackets) {
92 std::string message(1024, '\0');
93 std::unique_ptr<Socket> server, client;
David Pursell815c7be2015-12-09 17:09:54 -080094
David Pursell572bce22016-01-15 14:19:56 -080095 for (Socket::Protocol protocol : {Socket::Protocol::kUdp, Socket::Protocol::kTcp}) {
96 ASSERT_TRUE(MakeConnectedSockets(protocol, &server, &client));
David Pursell815c7be2015-12-09 17:09:54 -080097
David Pursell572bce22016-01-15 14:19:56 -080098 // Run through the test a few times.
99 for (int i = 0; i < 10; ++i) {
100 // Use a different message each iteration to prevent false positives.
101 for (size_t j = 0; j < message.length(); ++j) {
102 message[j] = static_cast<char>(i + j);
103 }
104
105 EXPECT_TRUE(SendString(client.get(), message));
106 EXPECT_TRUE(ReceiveString(server.get(), message));
David Pursell815c7be2015-12-09 17:09:54 -0800107 }
David Pursell815c7be2015-12-09 17:09:54 -0800108 }
109}
110
David Pursell572bce22016-01-15 14:19:56 -0800111// Tests UDP receive overflow when the UDP packet is larger than the receive buffer.
112TEST(SocketTest, TestUdpReceiveOverflow) {
113 std::unique_ptr<Socket> server, client;
114 ASSERT_TRUE(MakeConnectedSockets(Socket::Protocol::kUdp, &server, &client));
David Pursell815c7be2015-12-09 17:09:54 -0800115
David Pursell572bce22016-01-15 14:19:56 -0800116 EXPECT_TRUE(SendString(client.get(), "1234567890"));
David Pursell815c7be2015-12-09 17:09:54 -0800117
David Pursell572bce22016-01-15 14:19:56 -0800118 // This behaves differently on different systems, either truncating the packet or returning -1.
119 char buffer[5];
120 ssize_t bytes = server->Receive(buffer, 5, kTestTimeoutMs);
121 if (bytes == 5) {
122 EXPECT_EQ(0, memcmp(buffer, "12345", 5));
123 } else {
124 EXPECT_EQ(-1, bytes);
David Pursell815c7be2015-12-09 17:09:54 -0800125 }
126}