OLD | NEW |
| (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 "mojo/shell/domain_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 "base/message_loop/message_loop.h" | |
14 #include "base/posix/eintr_wrapper.h" | |
15 #include "mojo/shell/domain_socket/net_errors.h" | |
16 #include "mojo/shell/domain_socket/socket_libevent.h" | |
17 #include "mojo/shell/domain_socket/test_completion_callback.h" | |
18 #include "mojo/shell/domain_socket/unix_domain_server_socket_posix.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace mojo { | |
22 namespace shell { | |
23 namespace { | |
24 | |
25 const char kSocketFilename[] = "socket_for_testing"; | |
26 | |
27 bool UserCanConnectCallback( | |
28 bool allow_user, | |
29 const UnixDomainServerSocket::Credentials& credentials) { | |
30 // Here peers are running in same process. | |
31 EXPECT_EQ(getpid(), credentials.process_id); | |
32 EXPECT_EQ(getuid(), credentials.user_id); | |
33 EXPECT_EQ(getgid(), credentials.group_id); | |
34 return allow_user; | |
35 } | |
36 | |
37 UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) { | |
38 return base::Bind(&UserCanConnectCallback, allow_user); | |
39 } | |
40 | |
41 // Connects socket synchronously. | |
42 int ConnectSynchronously(UnixDomainClientSocket* socket) { | |
43 TestCompletionCallback connect_callback; | |
44 int rv = socket->Connect(connect_callback.callback()); | |
45 if (rv == net::ERR_IO_PENDING) | |
46 rv = connect_callback.WaitForResult(); | |
47 return rv; | |
48 } | |
49 } // namespace | |
50 | |
51 class UnixDomainClientSocketTest : public testing::Test { | |
52 protected: | |
53 UnixDomainClientSocketTest() { | |
54 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
55 socket_path_ = temp_dir_.path().Append(kSocketFilename).value(); | |
56 } | |
57 | |
58 base::ScopedTempDir temp_dir_; | |
59 std::string socket_path_; | |
60 base::MessageLoopForIO loop_; | |
61 }; | |
62 | |
63 TEST_F(UnixDomainClientSocketTest, ConnectWithSocketDescriptor) { | |
64 const bool kUseAbstractNamespace = false; | |
65 | |
66 UnixDomainServerSocket server_socket(CreateAuthCallback(true), | |
67 kUseAbstractNamespace); | |
68 EXPECT_EQ(net::OK, server_socket.ListenWithPath(socket_path_, 1)); | |
69 | |
70 SocketDescriptor accepted_socket_fd = kInvalidSocket; | |
71 TestCompletionCallback accept_callback; | |
72 EXPECT_EQ( | |
73 net::ERR_IO_PENDING, | |
74 server_socket.Accept(&accepted_socket_fd, accept_callback.callback())); | |
75 EXPECT_EQ(kInvalidSocket, accepted_socket_fd); | |
76 | |
77 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace); | |
78 EXPECT_FALSE(client_socket.IsConnected()); | |
79 | |
80 EXPECT_EQ(net::OK, ConnectSynchronously(&client_socket)); | |
81 EXPECT_TRUE(client_socket.IsConnected()); | |
82 // Server has not yet been notified of the connection. | |
83 EXPECT_EQ(kInvalidSocket, accepted_socket_fd); | |
84 | |
85 EXPECT_EQ(net::OK, accept_callback.WaitForResult()); | |
86 EXPECT_NE(kInvalidSocket, accepted_socket_fd); | |
87 | |
88 SocketDescriptor client_socket_fd = client_socket.ReleaseConnectedSocket(); | |
89 EXPECT_NE(kInvalidSocket, client_socket_fd); | |
90 | |
91 // Now, re-wrap client_socket_fd in a UnixDomainClientSocket and check that | |
92 // it hasn't gotten accidentally closed. | |
93 SockaddrStorage addr; | |
94 ASSERT_TRUE(UnixDomainClientSocket::FillAddress(socket_path_, false, &addr)); | |
95 scoped_ptr<SocketLibevent> adopter(new SocketLibevent); | |
96 adopter->AdoptConnectedSocket(client_socket_fd, addr); | |
97 UnixDomainClientSocket rewrapped_socket(adopter.Pass()); | |
98 EXPECT_TRUE(rewrapped_socket.IsConnected()); | |
99 | |
100 EXPECT_EQ(0, IGNORE_EINTR(close(accepted_socket_fd))); | |
101 } | |
102 | |
103 TEST_F(UnixDomainClientSocketTest, ConnectWithAbstractNamespace) { | |
104 const bool kUseAbstractNamespace = true; | |
105 | |
106 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace); | |
107 EXPECT_FALSE(client_socket.IsConnected()); | |
108 | |
109 UnixDomainServerSocket server_socket(CreateAuthCallback(true), | |
110 kUseAbstractNamespace); | |
111 EXPECT_EQ(net::OK, server_socket.ListenWithPath(socket_path_, 1)); | |
112 | |
113 SocketDescriptor accepted_socket_fd = kInvalidSocket; | |
114 TestCompletionCallback accept_callback; | |
115 EXPECT_EQ( | |
116 net::ERR_IO_PENDING, | |
117 server_socket.Accept(&accepted_socket_fd, accept_callback.callback())); | |
118 EXPECT_EQ(kInvalidSocket, accepted_socket_fd); | |
119 | |
120 EXPECT_EQ(net::OK, ConnectSynchronously(&client_socket)); | |
121 EXPECT_TRUE(client_socket.IsConnected()); | |
122 // Server has not yet been notified of the connection. | |
123 EXPECT_EQ(kInvalidSocket, accepted_socket_fd); | |
124 | |
125 EXPECT_EQ(net::OK, accept_callback.WaitForResult()); | |
126 EXPECT_NE(kInvalidSocket, accepted_socket_fd); | |
127 | |
128 EXPECT_EQ(0, IGNORE_EINTR(close(accepted_socket_fd))); | |
129 } | |
130 | |
131 TEST_F(UnixDomainClientSocketTest, ConnectToNonExistentSocket) { | |
132 const bool kUseAbstractNamespace = false; | |
133 | |
134 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace); | |
135 EXPECT_FALSE(client_socket.IsConnected()); | |
136 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, ConnectSynchronously(&client_socket)); | |
137 } | |
138 | |
139 TEST_F(UnixDomainClientSocketTest, | |
140 ConnectToNonExistentSocketWithAbstractNamespace) { | |
141 const bool kUseAbstractNamespace = true; | |
142 | |
143 UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace); | |
144 EXPECT_FALSE(client_socket.IsConnected()); | |
145 | |
146 TestCompletionCallback connect_callback; | |
147 EXPECT_EQ(net::ERR_CONNECTION_REFUSED, ConnectSynchronously(&client_socket)); | |
148 } | |
149 | |
150 } // namespace shell | |
151 } // namespace mojo | |
OLD | NEW |