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

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: Checked uid and gid in unittests. 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 // Reads data from |socket| until it fills |buf| at least up to |min_data_len|.
37 // Returns length of data read, or a net error.
38 int ReadSynchronously(StreamSocket* socket,
39 IOBuffer* buf,
40 int buf_len,
41 int min_data_len) {
42 scoped_refptr<DrainableIOBuffer> read_buf(
43 new DrainableIOBuffer(buf, buf_len));
44 TestCompletionCallback read_callback;
45 // Iterate reading several times (but not infinite) until it reads buf
46 // at least up to |min_data_len|.
47 for (int retry_count = 10;
48 retry_count > 0 && (read_buf->BytesConsumed() < min_data_len ||
49 // Try at least once when min_data_len == 0.
50 min_data_len == 0);
51 --retry_count) {
52 int rv = socket->Read(read_buf, read_buf->BytesRemaining(),
53 read_callback.callback());
54 EXPECT_GE(read_buf->BytesRemaining(), rv);
55 if (rv == ERR_IO_PENDING) {
56 // If |min_data_len| is 0, returns ERR_IO_PENDING to distinguish the case
57 // when some data has been read.
58 if (min_data_len == 0) {
59 // No data has been read because of for-loop condition.
60 DCHECK_EQ(0, read_buf->BytesConsumed());
61 return ERR_IO_PENDING;
62 }
63 rv = read_callback.WaitForResult();
64 }
65 EXPECT_NE(ERR_IO_PENDING, rv);
66 if (rv < 0)
67 return rv;
68 read_buf->DidConsume(rv);
69 }
70 EXPECT_LE(0, read_buf->BytesRemaining());
71 return read_buf->BytesConsumed();
72 }
73
74 // Writes data to |socket| until it completes writing |buf| up to |buf_len|.
75 // Returns length of data written, or a net error.
76 int WriteSynchronously(StreamSocket* socket,
77 IOBuffer* buf,
78 int buf_len) {
79 scoped_refptr<DrainableIOBuffer> write_buf(
80 new DrainableIOBuffer(buf, buf_len));
81 TestCompletionCallback write_callback;
82 // Iterate writing several times (but not infinite) until it writes buf fully.
83 for (int retry_count = 10;
84 retry_count > 0 && write_buf->BytesRemaining() > 0;
85 --retry_count) {
86 int rv = socket->Write(write_buf, write_buf->BytesRemaining(),
87 write_callback.callback());
88 EXPECT_GE(write_buf->BytesRemaining(), rv);
89 if (rv == ERR_IO_PENDING)
90 rv = write_callback.WaitForResult();
91 EXPECT_NE(ERR_IO_PENDING, rv);
92 if (rv < 0)
93 return rv;
94 write_buf->DidConsume(rv);
95 }
96 EXPECT_LE(0, write_buf->BytesRemaining());
97 return write_buf->BytesConsumed();
mmenke 2014/07/15 15:25:56 Still theoretically possible for these both to fai
byungchul 2014/07/15 17:30:45 Default socket write buffer is much bigger than th
mmenke 2014/07/15 19:12:57 My general feeling is that we should depend on pub
byungchul 2014/07/15 22:01:18 At least for write(), I think socket buffer size c
mmenke 2014/07/16 18:30:35 And that applies to all supported platforms that t
98 }
99
100 } // namespace
101
102 class UnixDomainClientSocketTest : public testing::Test {
103 protected:
104 UnixDomainClientSocketTest() {
105 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
106 socket_path_ = temp_dir_.path().Append(kSocketFilename).value();
107 }
108
109 base::ScopedTempDir temp_dir_;
110 std::string socket_path_;
111 };
112
113 TEST_F(UnixDomainClientSocketTest, Connect) {
114 const bool kUseAbstractNamespace = false;
115
116 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
117 kUseAbstractNamespace);
118 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
119
120 scoped_ptr<StreamSocket> accepted_socket;
121 TestCompletionCallback accept_callback;
122 EXPECT_EQ(ERR_IO_PENDING,
123 server_socket.Accept(&accepted_socket, accept_callback.callback()));
124 EXPECT_FALSE(accepted_socket);
125
126 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
127 EXPECT_FALSE(client_socket.IsConnected());
128
129 // Connect() returns OK synchronously before server gets accept event because
130 // kernel accepts the connection.
mmenke 2014/07/15 15:25:56 Since we now work with accepting the socket async,
byungchul 2014/07/15 17:30:45 Done.
131 TestCompletionCallback connect_callback;
132 int rv = client_socket.Connect(connect_callback.callback());
133 if (rv == ERR_IO_PENDING)
134 rv = connect_callback.WaitForResult();
135 EXPECT_EQ(OK, rv);
136 EXPECT_TRUE(client_socket.IsConnected());
137 // Server has not yet been notified of the connection.
138 EXPECT_FALSE(accepted_socket);
139
140 EXPECT_EQ(OK, accept_callback.WaitForResult());
141 EXPECT_TRUE(accepted_socket);
142 EXPECT_TRUE(accepted_socket->IsConnected());
143 }
144
145 TEST_F(UnixDomainClientSocketTest, ConnectWithAbstractNamespace) {
146 const bool kUseAbstractNamespace = true;
147
148 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
149 EXPECT_FALSE(client_socket.IsConnected());
150
151 #if defined(OS_ANDROID) || defined(OS_LINUX)
152 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
153 kUseAbstractNamespace);
154 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
155
156 scoped_ptr<StreamSocket> accepted_socket;
157 TestCompletionCallback accept_callback;
158 EXPECT_EQ(ERR_IO_PENDING,
159 server_socket.Accept(&accepted_socket, accept_callback.callback()));
160 EXPECT_FALSE(accepted_socket);
161
162 TestCompletionCallback connect_callback;
163 int rv = client_socket.Connect(connect_callback.callback());
164 if (rv == ERR_IO_PENDING)
165 rv = connect_callback.WaitForResult();
166 EXPECT_EQ(OK, rv);
167 EXPECT_TRUE(client_socket.IsConnected());
168 // Server has not yet beend notified of the connection.
169 EXPECT_FALSE(accepted_socket);
170
171 EXPECT_EQ(OK, accept_callback.WaitForResult());
172 EXPECT_TRUE(accepted_socket);
173 EXPECT_TRUE(accepted_socket->IsConnected());
174 #else
175 TestCompletionCallback connect_callback;
176 EXPECT_EQ(ERR_ADDRESS_INVALID,
177 client_socket.Connect(connect_callback.callback()));
178 #endif
179 }
180
181 TEST_F(UnixDomainClientSocketTest, ConnectToNonExistentSocket) {
182 const bool kUseAbstractNamespace = false;
183
184 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
185 EXPECT_FALSE(client_socket.IsConnected());
186
187 TestCompletionCallback connect_callback;
188 EXPECT_EQ(ERR_FILE_NOT_FOUND,
189 client_socket.Connect(connect_callback.callback()));
mmenke 2014/07/15 15:25:56 As with the successful connection tests, should al
byungchul 2014/07/15 17:30:45 I have no idea how to make async connect() for uni
mmenke 2014/07/15 17:44:41 Not suggesting you make them, just that these test
byungchul 2014/07/15 18:07:01 Oh, I see what you meant. Here, async is hanlded o
mmenke 2014/07/15 19:12:57 I see no code that guarantees this error case will
byungchul 2014/07/15 22:01:18 Done.
190 }
191
192 TEST_F(UnixDomainClientSocketTest,
193 ConnectToNonExistentSocketWithAbstractNamespace) {
194 const bool kUseAbstractNamespace = true;
195
196 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
197 EXPECT_FALSE(client_socket.IsConnected());
198
199 TestCompletionCallback connect_callback;
200 #if defined(OS_ANDROID) || defined(OS_LINUX)
201 EXPECT_EQ(ERR_CONNECTION_REFUSED,
202 client_socket.Connect(connect_callback.callback()));
203 #else
204 EXPECT_EQ(ERR_ADDRESS_INVALID,
205 client_socket.Connect(connect_callback.callback()));
206 #endif
207 }
208
209 TEST_F(UnixDomainClientSocketTest, DisconnectFromClient) {
210 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
211 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
212 scoped_ptr<StreamSocket> accepted_socket;
213 TestCompletionCallback accept_callback;
214 EXPECT_EQ(ERR_IO_PENDING,
215 server_socket.Accept(&accepted_socket, accept_callback.callback()));
216 UnixDomainClientSocket client_socket(socket_path_, false);
217 TestCompletionCallback connect_callback;
218 int rv = client_socket.Connect(connect_callback.callback());
219 if (rv == ERR_IO_PENDING)
220 rv = connect_callback.WaitForResult();
221 EXPECT_EQ(OK, rv);
222
223 EXPECT_EQ(OK, accept_callback.WaitForResult());
224 EXPECT_TRUE(accepted_socket->IsConnected());
225 EXPECT_TRUE(client_socket.IsConnected());
226
227 // Disconnect from client side.
228 client_socket.Disconnect();
229 EXPECT_FALSE(client_socket.IsConnected());
230 EXPECT_FALSE(accepted_socket->IsConnected());
231 }
232
233 TEST_F(UnixDomainClientSocketTest, DisconnectFromServer) {
mmenke 2014/07/15 15:25:56 Don't think we have any tests where we get a close
byungchul 2014/07/15 17:30:45 Done for reading.
234 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
235 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
236 scoped_ptr<StreamSocket> accepted_socket;
237 TestCompletionCallback accept_callback;
238 EXPECT_EQ(ERR_IO_PENDING,
239 server_socket.Accept(&accepted_socket, accept_callback.callback()));
240 UnixDomainClientSocket client_socket(socket_path_, false);
241 TestCompletionCallback connect_callback;
242 int rv = client_socket.Connect(connect_callback.callback());
243 if (rv == ERR_IO_PENDING)
244 rv = connect_callback.WaitForResult();
245 EXPECT_EQ(OK, rv);
246
247 EXPECT_EQ(OK, accept_callback.WaitForResult());
248 EXPECT_TRUE(accepted_socket->IsConnected());
249 EXPECT_TRUE(client_socket.IsConnected());
250
251 // Disconnect from server side.
252 accepted_socket->Disconnect();
253 EXPECT_FALSE(accepted_socket->IsConnected());
254 EXPECT_FALSE(client_socket.IsConnected());
255 }
256
257 TEST_F(UnixDomainClientSocketTest, ReadAfterWrite) {
258 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
259 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
260 scoped_ptr<StreamSocket> accepted_socket;
261 TestCompletionCallback accept_callback;
262 EXPECT_EQ(ERR_IO_PENDING,
263 server_socket.Accept(&accepted_socket, accept_callback.callback()));
264 UnixDomainClientSocket client_socket(socket_path_, false);
265 TestCompletionCallback connect_callback;
266 int rv = client_socket.Connect(connect_callback.callback());
267 if (rv == ERR_IO_PENDING)
268 rv = connect_callback.WaitForResult();
269 EXPECT_EQ(OK, rv);
270
271 EXPECT_EQ(OK, accept_callback.WaitForResult());
272 EXPECT_TRUE(accepted_socket->IsConnected());
273 EXPECT_TRUE(client_socket.IsConnected());
274
275 // Send data from client to server.
276 const int write_data_size = 10;
277 scoped_refptr<IOBuffer> write_buffer(
278 new StringIOBuffer(std::string(write_data_size, 'd')));
279 EXPECT_EQ(write_data_size,
280 WriteSynchronously(&client_socket,
281 write_buffer,
282 write_data_size));
283
284 // The buffer is bigger than write data size.
285 const int read_buffer_size = write_data_size * 2;
286 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(read_buffer_size));
287 EXPECT_EQ(write_data_size,
288 ReadSynchronously(accepted_socket.get(),
289 read_buffer,
290 read_buffer_size,
291 write_data_size));
292 EXPECT_EQ(std::string(write_buffer->data(), write_data_size),
293 std::string(read_buffer->data(), write_data_size));
294
295 // Send data from server and client.
296 EXPECT_EQ(write_data_size,
297 WriteSynchronously(accepted_socket.get(),
298 write_buffer,
299 write_data_size));
300
301 // Read multiple times.
302 const int small_read_buffer_size = write_data_size / 3;
303 EXPECT_EQ(small_read_buffer_size,
304 ReadSynchronously(&client_socket,
305 read_buffer,
306 small_read_buffer_size,
307 small_read_buffer_size));
308 EXPECT_EQ(std::string(write_buffer->data(), small_read_buffer_size),
309 std::string(read_buffer->data(), small_read_buffer_size));
310
311 EXPECT_EQ(write_data_size - small_read_buffer_size,
312 ReadSynchronously(&client_socket,
313 read_buffer,
314 read_buffer_size,
315 write_data_size - small_read_buffer_size));
316 EXPECT_EQ(std::string(write_buffer->data() + small_read_buffer_size,
317 write_data_size - small_read_buffer_size),
318 std::string(read_buffer->data(),
319 write_data_size - small_read_buffer_size));
320
321 // No more data.
322 EXPECT_EQ(ERR_IO_PENDING,
323 ReadSynchronously(&client_socket,
324 read_buffer,
325 read_buffer_size,
326 0));
327
328 // Disconnect from server side after read-write.
329 accepted_socket->Disconnect();
330 EXPECT_FALSE(accepted_socket->IsConnected());
331 EXPECT_FALSE(client_socket.IsConnected());
332 }
333
334 TEST_F(UnixDomainClientSocketTest, ReadBeforeWrite) {
335 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
336 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
337 scoped_ptr<StreamSocket> accepted_socket;
338 TestCompletionCallback accept_callback;
339 EXPECT_EQ(ERR_IO_PENDING,
340 server_socket.Accept(&accepted_socket, accept_callback.callback()));
341 UnixDomainClientSocket client_socket(socket_path_, false);
342 TestCompletionCallback connect_callback;
343 int rv = client_socket.Connect(connect_callback.callback());
344 if (rv == ERR_IO_PENDING)
345 rv = connect_callback.WaitForResult();
346 EXPECT_EQ(OK, rv);
347
348 EXPECT_EQ(OK, accept_callback.WaitForResult());
349 EXPECT_TRUE(accepted_socket->IsConnected());
350 EXPECT_TRUE(client_socket.IsConnected());
351
352 // Wait for data from client.
353 const int write_data_size = 10;
354 const int read_buffer_size = write_data_size * 2;
355 const int small_read_buffer_size = write_data_size / 3;
356 // Read smaller than write data size first.
357 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(read_buffer_size));
358 TestCompletionCallback read_callback;
359 EXPECT_EQ(ERR_IO_PENDING,
360 accepted_socket->Read(read_buffer, small_read_buffer_size,
361 read_callback.callback()));
362
363 scoped_refptr<IOBuffer> write_buffer(
364 new StringIOBuffer(std::string(write_data_size, 'd')));
365 EXPECT_EQ(write_data_size,
366 WriteSynchronously(&client_socket,
367 write_buffer,
368 write_data_size));
369
370 // First read completed.
371 EXPECT_EQ(small_read_buffer_size, read_callback.WaitForResult());
372 // Read remaining data.
373 EXPECT_EQ(write_data_size - small_read_buffer_size,
374 ReadSynchronously(accepted_socket.get(),
375 read_buffer,
376 read_buffer_size,
377 write_data_size - small_read_buffer_size));
378 // No more data.
379 EXPECT_EQ(ERR_IO_PENDING,
380 ReadSynchronously(accepted_socket.get(),
381 read_buffer,
382 read_buffer_size,
383 0));
384
385 // Disconnect from server side after read-write.
386 accepted_socket->Disconnect();
387 EXPECT_FALSE(accepted_socket->IsConnected());
388 EXPECT_FALSE(client_socket.IsConnected());
389 }
390
391 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698