• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 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 #include "async_manager.h"
18 #include <gtest/gtest.h>
19 #include <cstdint>
20 #include <cstring>
21 #include <vector>
22 
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 namespace test_vendor_lib {
30 
31 class AsyncManagerSocketTest : public ::testing::Test {
32  public:
33   static const uint16_t kPort = 6111;
34   static const size_t kBufferSize = 16;
35 
CheckBufferEquals()36   bool CheckBufferEquals() {
37     return strcmp(server_buffer_, client_buffer_) == 0;
38   }
39 
40  protected:
StartServer()41   int StartServer() {
42     struct sockaddr_in serv_addr;
43     int fd = socket(AF_INET, SOCK_STREAM, 0);
44     EXPECT_FALSE(fd < 0);
45 
46     memset(&serv_addr, 0, sizeof(serv_addr));
47     serv_addr.sin_family = AF_INET;
48     serv_addr.sin_addr.s_addr = INADDR_ANY;
49     serv_addr.sin_port = htons(kPort);
50     int reuse_flag = 1;
51     EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag,
52                             sizeof(reuse_flag)) < 0);
53     EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
54 
55     listen(fd, 1);
56     return fd;
57   }
58 
AcceptConnection(int fd)59   int AcceptConnection(int fd) {
60     struct sockaddr_in cli_addr;
61     memset(&cli_addr, 0, sizeof(cli_addr));
62     socklen_t clilen = sizeof(cli_addr);
63 
64     int connection_fd = accept(fd, (struct sockaddr*)&cli_addr, &clilen);
65     EXPECT_FALSE(connection_fd < 0);
66 
67     return connection_fd;
68   }
69 
ReadIncomingMessage(int fd)70   void ReadIncomingMessage(int fd) {
71     int n = TEMP_FAILURE_RETRY(read(fd, server_buffer_, kBufferSize - 1));
72     EXPECT_FALSE(n < 0);
73 
74     if (n == 0) {  // got EOF
75       async_manager_.StopWatchingFileDescriptor(fd);
76       close(fd);
77     } else {
78       n = write(fd, "1", 1);
79     }
80   }
81 
SetUp()82   void SetUp() override {
83     memset(server_buffer_, 0, kBufferSize);
84 
85     socket_fd_ = StartServer();
86 
87     async_manager_.WatchFdForNonBlockingReads(socket_fd_, [this](int fd) {
88       int connection_fd = AcceptConnection(fd);
89 
90       async_manager_.WatchFdForNonBlockingReads(
91           connection_fd, [this](int fd) { ReadIncomingMessage(fd); });
92     });
93   }
94 
TearDown()95   void TearDown() override {
96     async_manager_.StopWatchingFileDescriptor(socket_fd_);
97     close(socket_fd_);
98     EXPECT_TRUE(CheckBufferEquals());
99   }
100 
ConnectClient()101   int ConnectClient() {
102     int socket_cli_fd = socket(AF_INET, SOCK_STREAM, 0);
103     EXPECT_FALSE(socket_cli_fd < 0);
104 
105     struct hostent* server;
106     server = gethostbyname("localhost");
107     EXPECT_FALSE(server == NULL);
108 
109     struct sockaddr_in serv_addr;
110     memset((void*)&serv_addr, 0, sizeof(serv_addr));
111     serv_addr.sin_family = AF_INET;
112     serv_addr.sin_addr.s_addr = *(reinterpret_cast<in_addr_t*>(server->h_addr));
113     serv_addr.sin_port = htons(kPort);
114 
115     int result =
116         connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
117     EXPECT_FALSE(result < 0);
118 
119     return socket_cli_fd;
120   }
121 
WriteFromClient(int socket_cli_fd)122   void WriteFromClient(int socket_cli_fd) {
123     strcpy(client_buffer_, "1");
124     int n = write(socket_cli_fd, client_buffer_, strlen(client_buffer_));
125     EXPECT_TRUE(n > 0);
126   }
127 
AwaitServerResponse(int socket_cli_fd)128   void AwaitServerResponse(int socket_cli_fd) {
129     int n = read(socket_cli_fd, client_buffer_, 1);
130     EXPECT_TRUE(n > 0);
131   }
132 
133  private:
134   AsyncManager async_manager_;
135   int socket_fd_;
136   char server_buffer_[kBufferSize];
137   char client_buffer_[kBufferSize];
138 };
139 
TEST_F(AsyncManagerSocketTest,TestOneConnection)140 TEST_F(AsyncManagerSocketTest, TestOneConnection) {
141   int socket_cli_fd = ConnectClient();
142 
143   WriteFromClient(socket_cli_fd);
144 
145   AwaitServerResponse(socket_cli_fd);
146 
147   close(socket_cli_fd);
148 }
149 
TEST_F(AsyncManagerSocketTest,TestRepeatedConnections)150 TEST_F(AsyncManagerSocketTest, TestRepeatedConnections) {
151   static const int num_connections = 300;
152   for (int i = 0; i < num_connections; i++) {
153     int socket_cli_fd = ConnectClient();
154     WriteFromClient(socket_cli_fd);
155     AwaitServerResponse(socket_cli_fd);
156     close(socket_cli_fd);
157   }
158 }
159 
TEST_F(AsyncManagerSocketTest,TestMultipleConnections)160 TEST_F(AsyncManagerSocketTest, TestMultipleConnections) {
161   static const int num_connections = 300;
162   int socket_cli_fd[num_connections];
163   for (int i = 0; i < num_connections; i++) {
164     socket_cli_fd[i] = ConnectClient();
165     EXPECT_TRUE(socket_cli_fd[i] > 0);
166     WriteFromClient(socket_cli_fd[i]);
167   }
168   for (int i = 0; i < num_connections; i++) {
169     AwaitServerResponse(socket_cli_fd[i]);
170     close(socket_cli_fd[i]);
171   }
172 }
173 
174 }  // namespace test_vendor_lib
175