Chromecast: adds class to help record complex histograms.
[chromium-blink-merge.git] / net / socket / unix_domain_client_socket_posix_unittest.cc
blob651cd72dd5bb4611443b7e1d75df5574ec86134e
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.
5 #include "net/socket/unix_domain_client_socket_posix.h"
7 #include <unistd.h>
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 "base/posix/eintr_wrapper.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/socket/socket_libevent.h"
18 #include "net/socket/unix_domain_server_socket_posix.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace net {
22 namespace {
24 const char kSocketFilename[] = "socket_for_testing";
26 bool UserCanConnectCallback(
27 bool allow_user, const UnixDomainServerSocket::Credentials& credentials) {
28 // Here peers are running in same process.
29 #if defined(OS_LINUX) || defined(OS_ANDROID)
30 EXPECT_EQ(getpid(), credentials.process_id);
31 #endif
32 EXPECT_EQ(getuid(), credentials.user_id);
33 EXPECT_EQ(getgid(), credentials.group_id);
34 return allow_user;
37 UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) {
38 return base::Bind(&UserCanConnectCallback, allow_user);
41 // Connects socket synchronously.
42 int ConnectSynchronously(StreamSocket* socket) {
43 TestCompletionCallback connect_callback;
44 int rv = socket->Connect(connect_callback.callback());
45 if (rv == ERR_IO_PENDING)
46 rv = connect_callback.WaitForResult();
47 return rv;
50 // Reads data from |socket| until it fills |buf| at least up to |min_data_len|.
51 // Returns length of data read, or a net error.
52 int ReadSynchronously(StreamSocket* socket,
53 IOBuffer* buf,
54 int buf_len,
55 int min_data_len) {
56 DCHECK_LE(min_data_len, buf_len);
57 scoped_refptr<DrainableIOBuffer> read_buf(
58 new DrainableIOBuffer(buf, buf_len));
59 TestCompletionCallback read_callback;
60 // Iterate reading several times (but not infinite) until it reads at least
61 // |min_data_len| bytes into |buf|.
62 for (int retry_count = 10;
63 retry_count > 0 && (read_buf->BytesConsumed() < min_data_len ||
64 // Try at least once when min_data_len == 0.
65 min_data_len == 0);
66 --retry_count) {
67 int rv = socket->Read(
68 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
69 EXPECT_GE(read_buf->BytesRemaining(), rv);
70 if (rv == ERR_IO_PENDING) {
71 // If |min_data_len| is 0, returns ERR_IO_PENDING to distinguish the case
72 // when some data has been read.
73 if (min_data_len == 0) {
74 // No data has been read because of for-loop condition.
75 DCHECK_EQ(0, read_buf->BytesConsumed());
76 return ERR_IO_PENDING;
78 rv = read_callback.WaitForResult();
80 EXPECT_NE(ERR_IO_PENDING, rv);
81 if (rv < 0)
82 return rv;
83 read_buf->DidConsume(rv);
85 EXPECT_LE(0, read_buf->BytesRemaining());
86 return read_buf->BytesConsumed();
89 // Writes data to |socket| until it completes writing |buf| up to |buf_len|.
90 // Returns length of data written, or a net error.
91 int WriteSynchronously(StreamSocket* socket,
92 IOBuffer* buf,
93 int buf_len) {
94 scoped_refptr<DrainableIOBuffer> write_buf(
95 new DrainableIOBuffer(buf, buf_len));
96 TestCompletionCallback write_callback;
97 // Iterate writing several times (but not infinite) until it writes buf fully.
98 for (int retry_count = 10;
99 retry_count > 0 && write_buf->BytesRemaining() > 0;
100 --retry_count) {
101 int rv = socket->Write(write_buf.get(),
102 write_buf->BytesRemaining(),
103 write_callback.callback());
104 EXPECT_GE(write_buf->BytesRemaining(), rv);
105 if (rv == ERR_IO_PENDING)
106 rv = write_callback.WaitForResult();
107 EXPECT_NE(ERR_IO_PENDING, rv);
108 if (rv < 0)
109 return rv;
110 write_buf->DidConsume(rv);
112 EXPECT_LE(0, write_buf->BytesRemaining());
113 return write_buf->BytesConsumed();
116 class UnixDomainClientSocketTest : public testing::Test {
117 protected:
118 UnixDomainClientSocketTest() {
119 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
120 socket_path_ = temp_dir_.path().Append(kSocketFilename).value();
123 base::ScopedTempDir temp_dir_;
124 std::string socket_path_;
127 TEST_F(UnixDomainClientSocketTest, Connect) {
128 const bool kUseAbstractNamespace = false;
130 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
131 kUseAbstractNamespace);
132 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
134 scoped_ptr<StreamSocket> accepted_socket;
135 TestCompletionCallback accept_callback;
136 EXPECT_EQ(ERR_IO_PENDING,
137 server_socket.Accept(&accepted_socket, accept_callback.callback()));
138 EXPECT_FALSE(accepted_socket);
140 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
141 EXPECT_FALSE(client_socket.IsConnected());
143 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
144 EXPECT_TRUE(client_socket.IsConnected());
145 // Server has not yet been notified of the connection.
146 EXPECT_FALSE(accepted_socket);
148 EXPECT_EQ(OK, accept_callback.WaitForResult());
149 EXPECT_TRUE(accepted_socket);
150 EXPECT_TRUE(accepted_socket->IsConnected());
153 TEST_F(UnixDomainClientSocketTest, ConnectWithSocketDescriptor) {
154 const bool kUseAbstractNamespace = false;
156 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
157 kUseAbstractNamespace);
158 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
160 SocketDescriptor accepted_socket_fd = kInvalidSocket;
161 TestCompletionCallback accept_callback;
162 EXPECT_EQ(ERR_IO_PENDING,
163 server_socket.AcceptSocketDescriptor(&accepted_socket_fd,
164 accept_callback.callback()));
165 EXPECT_EQ(kInvalidSocket, accepted_socket_fd);
167 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
168 EXPECT_FALSE(client_socket.IsConnected());
170 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
171 EXPECT_TRUE(client_socket.IsConnected());
172 // Server has not yet been notified of the connection.
173 EXPECT_EQ(kInvalidSocket, accepted_socket_fd);
175 EXPECT_EQ(OK, accept_callback.WaitForResult());
176 EXPECT_NE(kInvalidSocket, accepted_socket_fd);
178 SocketDescriptor client_socket_fd = client_socket.ReleaseConnectedSocket();
179 EXPECT_NE(kInvalidSocket, client_socket_fd);
181 // Now, re-wrap client_socket_fd in a UnixDomainClientSocket and try a read
182 // to be sure it hasn't gotten accidentally closed.
183 SockaddrStorage addr;
184 ASSERT_TRUE(UnixDomainClientSocket::FillAddress(socket_path_, false, &addr));
185 scoped_ptr<SocketLibevent> adopter(new SocketLibevent);
186 adopter->AdoptConnectedSocket(client_socket_fd, addr);
187 UnixDomainClientSocket rewrapped_socket(adopter.Pass());
188 EXPECT_TRUE(rewrapped_socket.IsConnected());
190 // Try to read data.
191 const int kReadDataSize = 10;
192 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadDataSize));
193 TestCompletionCallback read_callback;
194 EXPECT_EQ(ERR_IO_PENDING,
195 rewrapped_socket.Read(
196 read_buffer.get(), kReadDataSize, read_callback.callback()));
198 EXPECT_EQ(0, IGNORE_EINTR(close(accepted_socket_fd)));
201 TEST_F(UnixDomainClientSocketTest, ConnectWithAbstractNamespace) {
202 const bool kUseAbstractNamespace = true;
204 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
205 EXPECT_FALSE(client_socket.IsConnected());
207 #if defined(OS_ANDROID) || defined(OS_LINUX)
208 UnixDomainServerSocket server_socket(CreateAuthCallback(true),
209 kUseAbstractNamespace);
210 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 EXPECT_FALSE(accepted_socket);
218 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
219 EXPECT_TRUE(client_socket.IsConnected());
220 // Server has not yet beend notified of the connection.
221 EXPECT_FALSE(accepted_socket);
223 EXPECT_EQ(OK, accept_callback.WaitForResult());
224 EXPECT_TRUE(accepted_socket);
225 EXPECT_TRUE(accepted_socket->IsConnected());
226 #else
227 EXPECT_EQ(ERR_ADDRESS_INVALID, ConnectSynchronously(&client_socket));
228 #endif
231 TEST_F(UnixDomainClientSocketTest, ConnectToNonExistentSocket) {
232 const bool kUseAbstractNamespace = false;
234 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
235 EXPECT_FALSE(client_socket.IsConnected());
236 EXPECT_EQ(ERR_FILE_NOT_FOUND, ConnectSynchronously(&client_socket));
239 TEST_F(UnixDomainClientSocketTest,
240 ConnectToNonExistentSocketWithAbstractNamespace) {
241 const bool kUseAbstractNamespace = true;
243 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
244 EXPECT_FALSE(client_socket.IsConnected());
246 TestCompletionCallback connect_callback;
247 #if defined(OS_ANDROID) || defined(OS_LINUX)
248 EXPECT_EQ(ERR_CONNECTION_REFUSED, ConnectSynchronously(&client_socket));
249 #else
250 EXPECT_EQ(ERR_ADDRESS_INVALID, ConnectSynchronously(&client_socket));
251 #endif
254 TEST_F(UnixDomainClientSocketTest, DisconnectFromClient) {
255 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
256 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
257 scoped_ptr<StreamSocket> accepted_socket;
258 TestCompletionCallback accept_callback;
259 EXPECT_EQ(ERR_IO_PENDING,
260 server_socket.Accept(&accepted_socket, accept_callback.callback()));
261 UnixDomainClientSocket client_socket(socket_path_, false);
262 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
264 EXPECT_EQ(OK, accept_callback.WaitForResult());
265 EXPECT_TRUE(accepted_socket->IsConnected());
266 EXPECT_TRUE(client_socket.IsConnected());
268 // Try to read data.
269 const int kReadDataSize = 10;
270 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadDataSize));
271 TestCompletionCallback read_callback;
272 EXPECT_EQ(ERR_IO_PENDING,
273 accepted_socket->Read(
274 read_buffer.get(), kReadDataSize, read_callback.callback()));
276 // Disconnect from client side.
277 client_socket.Disconnect();
278 EXPECT_FALSE(client_socket.IsConnected());
279 EXPECT_FALSE(accepted_socket->IsConnected());
281 // Connection closed by peer.
282 EXPECT_EQ(0 /* EOF */, read_callback.WaitForResult());
283 // Note that read callback won't be called when the connection is closed
284 // locally before the peer closes it. SocketLibevent just clears callbacks.
287 TEST_F(UnixDomainClientSocketTest, DisconnectFromServer) {
288 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
289 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
290 scoped_ptr<StreamSocket> accepted_socket;
291 TestCompletionCallback accept_callback;
292 EXPECT_EQ(ERR_IO_PENDING,
293 server_socket.Accept(&accepted_socket, accept_callback.callback()));
294 UnixDomainClientSocket client_socket(socket_path_, false);
295 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
297 EXPECT_EQ(OK, accept_callback.WaitForResult());
298 EXPECT_TRUE(accepted_socket->IsConnected());
299 EXPECT_TRUE(client_socket.IsConnected());
301 // Try to read data.
302 const int kReadDataSize = 10;
303 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadDataSize));
304 TestCompletionCallback read_callback;
305 EXPECT_EQ(ERR_IO_PENDING,
306 client_socket.Read(
307 read_buffer.get(), kReadDataSize, read_callback.callback()));
309 // Disconnect from server side.
310 accepted_socket->Disconnect();
311 EXPECT_FALSE(accepted_socket->IsConnected());
312 EXPECT_FALSE(client_socket.IsConnected());
314 // Connection closed by peer.
315 EXPECT_EQ(0 /* EOF */, read_callback.WaitForResult());
316 // Note that read callback won't be called when the connection is closed
317 // locally before the peer closes it. SocketLibevent just clears callbacks.
320 TEST_F(UnixDomainClientSocketTest, ReadAfterWrite) {
321 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
322 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
323 scoped_ptr<StreamSocket> accepted_socket;
324 TestCompletionCallback accept_callback;
325 EXPECT_EQ(ERR_IO_PENDING,
326 server_socket.Accept(&accepted_socket, accept_callback.callback()));
327 UnixDomainClientSocket client_socket(socket_path_, false);
328 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
330 EXPECT_EQ(OK, accept_callback.WaitForResult());
331 EXPECT_TRUE(accepted_socket->IsConnected());
332 EXPECT_TRUE(client_socket.IsConnected());
334 // Send data from client to server.
335 const int kWriteDataSize = 10;
336 scoped_refptr<IOBuffer> write_buffer(
337 new StringIOBuffer(std::string(kWriteDataSize, 'd')));
338 EXPECT_EQ(
339 kWriteDataSize,
340 WriteSynchronously(&client_socket, write_buffer.get(), kWriteDataSize));
342 // The buffer is bigger than write data size.
343 const int kReadBufferSize = kWriteDataSize * 2;
344 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
345 EXPECT_EQ(kWriteDataSize,
346 ReadSynchronously(accepted_socket.get(),
347 read_buffer.get(),
348 kReadBufferSize,
349 kWriteDataSize));
350 EXPECT_EQ(std::string(write_buffer->data(), kWriteDataSize),
351 std::string(read_buffer->data(), kWriteDataSize));
353 // Send data from server and client.
354 EXPECT_EQ(kWriteDataSize,
355 WriteSynchronously(
356 accepted_socket.get(), write_buffer.get(), kWriteDataSize));
358 // Read multiple times.
359 const int kSmallReadBufferSize = kWriteDataSize / 3;
360 EXPECT_EQ(kSmallReadBufferSize,
361 ReadSynchronously(&client_socket,
362 read_buffer.get(),
363 kSmallReadBufferSize,
364 kSmallReadBufferSize));
365 EXPECT_EQ(std::string(write_buffer->data(), kSmallReadBufferSize),
366 std::string(read_buffer->data(), kSmallReadBufferSize));
368 EXPECT_EQ(kWriteDataSize - kSmallReadBufferSize,
369 ReadSynchronously(&client_socket,
370 read_buffer.get(),
371 kReadBufferSize,
372 kWriteDataSize - kSmallReadBufferSize));
373 EXPECT_EQ(std::string(write_buffer->data() + kSmallReadBufferSize,
374 kWriteDataSize - kSmallReadBufferSize),
375 std::string(read_buffer->data(),
376 kWriteDataSize - kSmallReadBufferSize));
378 // No more data.
379 EXPECT_EQ(
380 ERR_IO_PENDING,
381 ReadSynchronously(&client_socket, read_buffer.get(), kReadBufferSize, 0));
383 // Disconnect from server side after read-write.
384 accepted_socket->Disconnect();
385 EXPECT_FALSE(accepted_socket->IsConnected());
386 EXPECT_FALSE(client_socket.IsConnected());
389 TEST_F(UnixDomainClientSocketTest, ReadBeforeWrite) {
390 UnixDomainServerSocket server_socket(CreateAuthCallback(true), false);
391 EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
392 scoped_ptr<StreamSocket> accepted_socket;
393 TestCompletionCallback accept_callback;
394 EXPECT_EQ(ERR_IO_PENDING,
395 server_socket.Accept(&accepted_socket, accept_callback.callback()));
396 UnixDomainClientSocket client_socket(socket_path_, false);
397 EXPECT_EQ(OK, ConnectSynchronously(&client_socket));
399 EXPECT_EQ(OK, accept_callback.WaitForResult());
400 EXPECT_TRUE(accepted_socket->IsConnected());
401 EXPECT_TRUE(client_socket.IsConnected());
403 // Wait for data from client.
404 const int kWriteDataSize = 10;
405 const int kReadBufferSize = kWriteDataSize * 2;
406 const int kSmallReadBufferSize = kWriteDataSize / 3;
407 // Read smaller than write data size first.
408 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
409 TestCompletionCallback read_callback;
410 EXPECT_EQ(
411 ERR_IO_PENDING,
412 accepted_socket->Read(
413 read_buffer.get(), kSmallReadBufferSize, read_callback.callback()));
415 scoped_refptr<IOBuffer> write_buffer(
416 new StringIOBuffer(std::string(kWriteDataSize, 'd')));
417 EXPECT_EQ(
418 kWriteDataSize,
419 WriteSynchronously(&client_socket, write_buffer.get(), kWriteDataSize));
421 // First read completed.
422 int rv = read_callback.WaitForResult();
423 EXPECT_LT(0, rv);
424 EXPECT_LE(rv, kSmallReadBufferSize);
426 // Read remaining data.
427 const int kExpectedRemainingDataSize = kWriteDataSize - rv;
428 EXPECT_LE(0, kExpectedRemainingDataSize);
429 EXPECT_EQ(kExpectedRemainingDataSize,
430 ReadSynchronously(accepted_socket.get(),
431 read_buffer.get(),
432 kReadBufferSize,
433 kExpectedRemainingDataSize));
434 // No more data.
435 EXPECT_EQ(ERR_IO_PENDING,
436 ReadSynchronously(
437 accepted_socket.get(), read_buffer.get(), kReadBufferSize, 0));
439 // Disconnect from server side after read-write.
440 accepted_socket->Disconnect();
441 EXPECT_FALSE(accepted_socket->IsConnected());
442 EXPECT_FALSE(client_socket.IsConnected());
445 } // namespace
446 } // namespace net