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

Side by Side Diff: net/socket/unix_domain_client_socket_posix_unittest.cc

Issue 376323002: Refactor unix domain socket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make all connect in unittests synchronous. Created 6 years, 5 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "net/socket/unix_domain_client_socket_posix.h"
6
7 #include <unistd.h>
8
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/socket/unix_domain_server_socket_posix.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace net {
20
21 namespace {
22
23 const char kSocketFilename[] = "unix_domain_socket_for_testing";
24
25 bool UserCanConnectCallback(bool allow_user, uid_t uid, gid_t gid) {
26 // Here peers are running in same process. Check if they are expected.
27 EXPECT_EQ(getuid(), uid);
28 EXPECT_EQ(getgid(), gid);
29 return allow_user;
30 }
31
32 UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) {
33 return base::Bind(&UserCanConnectCallback, allow_user);
34 }
35
36 // Connects socket synchronously.
37 int ConnectSynchronously(StreamSocket* socket) {
38 TestCompletionCallback connect_callback;
39 int rv = socket->Connect(connect_callback.callback());
40 if (rv == ERR_IO_PENDING)
41 rv = connect_callback.WaitForResult();
42 return rv;
43 }
44
45 // Reads data from |socket| until it fills |buf| at least up to |min_data_len|.
46 // Returns length of data read, or a net error.
47 int ReadSynchronously(StreamSocket* socket,
48 IOBuffer* buf,
49 int buf_len,
50 int min_data_len) {
51 scoped_refptr<DrainableIOBuffer> read_buf(
52 new DrainableIOBuffer(buf, buf_len));
53 TestCompletionCallback read_callback;
54 // Iterate reading several times (but not infinite) until it reads buf
55 // at least up to |min_data_len|.
56 for (int retry_count = 10;
57 retry_count > 0 && (read_buf->BytesConsumed() < min_data_len ||
58 // Try at least once when min_data_len == 0.
59 min_data_len == 0);
60 --retry_count) {
61 int rv = socket->Read(read_buf, read_buf->BytesRemaining(),
62 read_callback.callback());
63 EXPECT_GE(read_buf->BytesRemaining(), rv);
64 if (rv == ERR_IO_PENDING) {
65 // If |min_data_len| is 0, returns ERR_IO_PENDING to distinguish the case
66 // when some data has been read.
67 if (min_data_len == 0) {
68 // No data has been read because of for-loop condition.
69 DCHECK_EQ(0, read_buf->BytesConsumed());
70 return ERR_IO_PENDING;
71 }
72 rv = read_callback.WaitForResult();
73 }
74 EXPECT_NE(ERR_IO_PENDING, rv);
75 if (rv < 0)
76 return rv;
77 read_buf->DidConsume(rv);
78 }
79 EXPECT_LE(0, read_buf->BytesRemaining());
80 return read_buf->BytesConsumed();
81 }
82
83 // Writes data to |socket| until it completes writing |buf| up to |buf_len|.
84 // Returns length of data written, or a net error.
85 int WriteSynchronously(StreamSocket* socket,
86 IOBuffer* buf,
87 int buf_len) {
88 scoped_refptr<DrainableIOBuffer> write_buf(
89 new DrainableIOBuffer(buf, buf_len));
90 TestCompletionCallback write_callback;
91 // Iterate writing several times (but not infinite) until it writes buf fully.
92 for (int retry_count = 10;
93 retry_count > 0 && write_buf->BytesRemaining() > 0;
94 --retry_count) {
95 int rv = socket->Write(write_buf, write_buf->BytesRemaining(),
96 write_callback.callback());
97 EXPECT_GE(write_buf->BytesRemaining(), rv);
98 if (rv == ERR_IO_PENDING)
99 rv = write_callback.WaitForResult();
100 EXPECT_NE(ERR_IO_PENDING, rv);
101 if (rv < 0)
102 return rv;
103 write_buf->DidConsume(rv);
104 }
105 EXPECT_LE(0, write_buf->BytesRemaining());
106 return write_buf->BytesConsumed();
107 }
108
109 } // namespace
110
111 class UnixDomainClientSocketTest : public testing::Test {
112 protected:
113 UnixDomainClientSocketTest() {
114 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
115 socket_path_ = temp_dir_.path().Append(kSocketFilename).value();
116 }
117
118 base::ScopedTempDir temp_dir_;
119 std::string socket_path_;
120 };
121
122 TEST_F(UnixDomainClientSocketTest, Connect) {
123 const bool kUseAbstractNamespace = false;
124
125 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
126 kUseAbstractNamespace);
127 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
128
129 scoped_ptr<StreamSocket> accepted_socket;
130 TestCompletionCallback accept_callback;
131 EXPECT_EQ(ERR_IO_PENDING,
132 server_socket.Accept(&accepted_socket, accept_callback.callback()));
133 EXPECT_FALSE(accepted_socket);
134
135 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
136 EXPECT_FALSE(client_socket.IsConnected());
137
138 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
139 EXPECT_TRUE(client_socket.IsConnected());
140 // Server has not yet been notified of the connection.
141 EXPECT_FALSE(accepted_socket);
142
143 EXPECT_EQ(OK, accept_callback.WaitForResult());
144 EXPECT_TRUE(accepted_socket);
145 EXPECT_TRUE(accepted_socket->IsConnected());
146 }
147
148 TEST_F(UnixDomainClientSocketTest, ConnectWithAbstractNamespace) {
149 const bool kUseAbstractNamespace = true;
150
151 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
152 EXPECT_FALSE(client_socket.IsConnected());
153
154 #if defined(OS_ANDROID) || defined(OS_LINUX)
155 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
156 kUseAbstractNamespace);
157 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
158
159 scoped_ptr<StreamSocket> accepted_socket;
160 TestCompletionCallback accept_callback;
161 EXPECT_EQ(ERR_IO_PENDING,
162 server_socket.Accept(&accepted_socket, accept_callback.callback()));
163 EXPECT_FALSE(accepted_socket);
164
165 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
166 EXPECT_TRUE(client_socket.IsConnected());
167 // Server has not yet beend notified of the connection.
168 EXPECT_FALSE(accepted_socket);
169
170 EXPECT_EQ(OK, accept_callback.WaitForResult());
171 EXPECT_TRUE(accepted_socket);
172 EXPECT_TRUE(accepted_socket->IsConnected());
173 #else
174 EXPECT_EQ(ERR_ADDRESS_INVALID, ConnectSynchronously(&client_socket));
175 #endif
176 }
177
178 TEST_F(UnixDomainClientSocketTest, ConnectToNonExistentSocket) {
179 const bool kUseAbstractNamespace = false;
180
181 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
182 EXPECT_FALSE(client_socket.IsConnected());
183 EXPECT_EQ(ERR_FILE_NOT_FOUND, ConnectSynchronously(&client_socket));
184 }
185
186 TEST_F(UnixDomainClientSocketTest,
187 ConnectToNonExistentSocketWithAbstractNamespace) {
188 const bool kUseAbstractNamespace = true;
189
190 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
191 EXPECT_FALSE(client_socket.IsConnected());
192
193 TestCompletionCallback connect_callback;
194 #if defined(OS_ANDROID) || defined(OS_LINUX)
195 EXPECT_EQ(ERR_CONNECTION_REFUSED,
196 client_socket.Connect(connect_callback.callback()));
197 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
mmenke 2014/07/16 18:30:35 This is a bug, right?
byungchul 2014/07/16 22:02:30 Oops, sorry. Done.
198 #else
199 EXPECT_EQ(ERR_ADDRESS_INVALID,
200 client_socket.Connect(connect_callback.callback()));
201 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
202 #endif
203 }
204
205 TEST_F(UnixDomainClientSocketTest, DisconnectFromClient) {
206 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
207 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
208 scoped_ptr<StreamSocket> accepted_socket;
209 TestCompletionCallback accept_callback;
210 EXPECT_EQ(ERR_IO_PENDING,
211 server_socket.Accept(&accepted_socket, accept_callback.callback()));
212 UnixDomainClientSocket client_socket(socket_path_, false);
213 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
214
215 EXPECT_EQ(OK, accept_callback.WaitForResult());
216 EXPECT_TRUE(accepted_socket->IsConnected());
217 EXPECT_TRUE(client_socket.IsConnected());
218
219 // Wait for read event.
mmenke 2014/07/16 18:30:35 nit: This isn't accurate - we're not waiting, we'
byungchul 2014/07/16 22:02:30 Done.
220 const int kWriteDataSize = 10;
mmenke 2014/07/16 18:30:35 nit: kReadDataSize?
byungchul 2014/07/16 22:02:30 Done.
221 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kWriteDataSize));
222 TestCompletionCallback read_callback;
223 EXPECT_EQ(ERR_IO_PENDING,
224 accepted_socket->Read(read_buffer, kWriteDataSize,
225 read_callback.callback()));
226
227 // Disconnect from client side.
228 client_socket.Disconnect();
229 EXPECT_FALSE(client_socket.IsConnected());
230 EXPECT_FALSE(accepted_socket->IsConnected());
231
232 // Connection closed by peer.
233 EXPECT_EQ(0 /* EOF */, read_callback.WaitForResult());
234 // Note that read callback won't be called when the connection is closed
235 // by local. SocketLibevent just clears callbacks.
mmenke 2014/07/16 18:30:35 "by local" -> "locally" or maybe "locally, before
byungchul 2014/07/16 22:02:30 Done.
236 }
237
238 TEST_F(UnixDomainClientSocketTest, DisconnectFromServer) {
239 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
240 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
241 scoped_ptr<StreamSocket> accepted_socket;
242 TestCompletionCallback accept_callback;
243 EXPECT_EQ(ERR_IO_PENDING,
244 server_socket.Accept(&accepted_socket, accept_callback.callback()));
245 UnixDomainClientSocket client_socket(socket_path_, false);
246 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
247
248 EXPECT_EQ(OK, accept_callback.WaitForResult());
249 EXPECT_TRUE(accepted_socket->IsConnected());
250 EXPECT_TRUE(client_socket.IsConnected());
251
252 // Wait for read event.
253 const int kWriteDataSize = 10;
254 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kWriteDataSize));
255 TestCompletionCallback read_callback;
256 EXPECT_EQ(ERR_IO_PENDING,
257 client_socket.Read(read_buffer, kWriteDataSize,
258 read_callback.callback()));
259
260 // Disconnect from server side.
261 accepted_socket->Disconnect();
262 EXPECT_FALSE(accepted_socket->IsConnected());
263 EXPECT_FALSE(client_socket.IsConnected());
264
265 // Connection closed by peer.
266 EXPECT_EQ(0 /* EOF */, read_callback.WaitForResult());
267 // Note that read callback won't be called when the connection is closed
268 // by local. SocketLibevent just clears callbacks.
269 }
270
271 TEST_F(UnixDomainClientSocketTest, ReadAfterWrite) {
272 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
273 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
274 scoped_ptr<StreamSocket> accepted_socket;
275 TestCompletionCallback accept_callback;
276 EXPECT_EQ(ERR_IO_PENDING,
277 server_socket.Accept(&accepted_socket, accept_callback.callback()));
278 UnixDomainClientSocket client_socket(socket_path_, false);
279 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
280
281 EXPECT_EQ(OK, accept_callback.WaitForResult());
282 EXPECT_TRUE(accepted_socket->IsConnected());
283 EXPECT_TRUE(client_socket.IsConnected());
284
285 // Send data from client to server.
286 const int kWriteDataSize = 10;
287 scoped_refptr<IOBuffer> write_buffer(
288 new StringIOBuffer(std::string(kWriteDataSize, 'd')));
289 EXPECT_EQ(kWriteDataSize,
290 WriteSynchronously(&client_socket,
291 write_buffer,
292 kWriteDataSize));
293
294 // The buffer is bigger than write data size.
295 const int kReadBufferSize = kWriteDataSize * 2;
296 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
297 EXPECT_EQ(kWriteDataSize,
298 ReadSynchronously(accepted_socket.get(),
299 read_buffer,
300 kReadBufferSize,
301 kWriteDataSize));
302 EXPECT_EQ(std::string(write_buffer->data(), kWriteDataSize),
303 std::string(read_buffer->data(), kWriteDataSize));
304
305 // Send data from server and client.
306 EXPECT_EQ(kWriteDataSize,
307 WriteSynchronously(accepted_socket.get(),
308 write_buffer,
309 kWriteDataSize));
310
311 // Read multiple times.
312 const int kSmallReadBufferSize = kWriteDataSize / 3;
313 EXPECT_EQ(kSmallReadBufferSize,
314 ReadSynchronously(&client_socket,
315 read_buffer,
316 kSmallReadBufferSize,
317 kSmallReadBufferSize));
318 EXPECT_EQ(std::string(write_buffer->data(), kSmallReadBufferSize),
319 std::string(read_buffer->data(), kSmallReadBufferSize));
320
321 EXPECT_EQ(kWriteDataSize - kSmallReadBufferSize,
322 ReadSynchronously(&client_socket,
323 read_buffer,
324 kReadBufferSize,
325 kWriteDataSize - kSmallReadBufferSize));
326 EXPECT_EQ(std::string(write_buffer->data() + kSmallReadBufferSize,
327 kWriteDataSize - kSmallReadBufferSize),
328 std::string(read_buffer->data(),
329 kWriteDataSize - kSmallReadBufferSize));
330
331 // No more data.
332 EXPECT_EQ(ERR_IO_PENDING,
333 ReadSynchronously(&client_socket,
334 read_buffer,
335 kReadBufferSize,
336 0));
337
338 // Disconnect from server side after read-write.
339 accepted_socket->Disconnect();
340 EXPECT_FALSE(accepted_socket->IsConnected());
341 EXPECT_FALSE(client_socket.IsConnected());
342 }
343
344 TEST_F(UnixDomainClientSocketTest, ReadBeforeWrite) {
345 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
346 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
347 scoped_ptr<StreamSocket> accepted_socket;
348 TestCompletionCallback accept_callback;
349 EXPECT_EQ(ERR_IO_PENDING,
350 server_socket.Accept(&accepted_socket, accept_callback.callback()));
351 UnixDomainClientSocket client_socket(socket_path_, false);
352 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
353
354 EXPECT_EQ(OK, accept_callback.WaitForResult());
355 EXPECT_TRUE(accepted_socket->IsConnected());
356 EXPECT_TRUE(client_socket.IsConnected());
357
358 // Wait for data from client.
359 const int kWriteDataSize = 10;
360 const int kReadBufferSize = kWriteDataSize * 2;
361 const int kSmallReadBufferSize = kWriteDataSize / 3;
362 // Read smaller than write data size first.
363 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
364 TestCompletionCallback read_callback;
365 EXPECT_EQ(ERR_IO_PENDING,
366 accepted_socket->Read(read_buffer, kSmallReadBufferSize,
367 read_callback.callback()));
368
369 scoped_refptr<IOBuffer> write_buffer(
370 new StringIOBuffer(std::string(kWriteDataSize, 'd')));
371 EXPECT_EQ(kWriteDataSize,
372 WriteSynchronously(&client_socket,
373 write_buffer,
374 kWriteDataSize));
375
376 // First read completed.
377 EXPECT_EQ(kSmallReadBufferSize, read_callback.WaitForResult());
378 // Read remaining data.
379 EXPECT_EQ(kWriteDataSize - kSmallReadBufferSize,
380 ReadSynchronously(accepted_socket.get(),
381 read_buffer,
382 kReadBufferSize,
383 kWriteDataSize - kSmallReadBufferSize));
384 // No more data.
385 EXPECT_EQ(ERR_IO_PENDING,
386 ReadSynchronously(accepted_socket.get(),
387 read_buffer,
388 kReadBufferSize,
389 0));
390
391 // Disconnect from server side after read-write.
392 accepted_socket->Disconnect();
393 EXPECT_FALSE(accepted_socket->IsConnected());
394 EXPECT_FALSE(client_socket.IsConnected());
395 }
396
397 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698