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

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

Issue 376323002: Refactor unix domain socket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix unittests because of incomplete reversion 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/unix_domain_listen_socket_posix.h"
6
5 #include <errno.h> 7 #include <errno.h>
6 #include <fcntl.h> 8 #include <fcntl.h>
7 #include <poll.h> 9 #include <poll.h>
8 #include <sys/socket.h> 10 #include <sys/socket.h>
9 #include <sys/stat.h> 11 #include <sys/stat.h>
10 #include <sys/time.h> 12 #include <sys/time.h>
11 #include <sys/types.h> 13 #include <sys/types.h>
12 #include <sys/un.h> 14 #include <sys/un.h>
13 #include <unistd.h> 15 #include <unistd.h>
14 16
15 #include <cstring> 17 #include <cstring>
16 #include <queue> 18 #include <queue>
17 #include <string> 19 #include <string>
18 20
19 #include "base/bind.h" 21 #include "base/bind.h"
20 #include "base/callback.h" 22 #include "base/callback.h"
21 #include "base/compiler_specific.h" 23 #include "base/compiler_specific.h"
22 #include "base/file_util.h" 24 #include "base/file_util.h"
23 #include "base/files/file_path.h" 25 #include "base/files/file_path.h"
24 #include "base/memory/ref_counted.h" 26 #include "base/memory/ref_counted.h"
25 #include "base/memory/scoped_ptr.h" 27 #include "base/memory/scoped_ptr.h"
26 #include "base/message_loop/message_loop.h" 28 #include "base/message_loop/message_loop.h"
27 #include "base/posix/eintr_wrapper.h" 29 #include "base/posix/eintr_wrapper.h"
28 #include "base/synchronization/condition_variable.h" 30 #include "base/synchronization/condition_variable.h"
29 #include "base/synchronization/lock.h" 31 #include "base/synchronization/lock.h"
30 #include "base/threading/platform_thread.h" 32 #include "base/threading/platform_thread.h"
31 #include "base/threading/thread.h" 33 #include "base/threading/thread.h"
32 #include "net/socket/socket_descriptor.h" 34 #include "net/socket/socket_descriptor.h"
33 #include "net/socket/unix_domain_socket_posix.h"
34 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
35 36
36 using std::queue; 37 using std::queue;
37 using std::string; 38 using std::string;
38 39
39 namespace net { 40 namespace net {
40 namespace { 41 namespace {
41 42
42 const char kSocketFilename[] = "unix_domain_socket_for_testing"; 43 const char kSocketFilename[] = "unix_domain_socket_for_testing";
43 const char kInvalidSocketPath[] = "/invalid/path"; 44 const char kInvalidSocketPath[] = "/invalid/path";
44 const char kMsg[] = "hello"; 45 const char kMsg[] = "hello";
45 46
46 enum EventType { 47 enum EventType {
47 EVENT_ACCEPT, 48 EVENT_ACCEPT,
48 EVENT_AUTH_DENIED, 49 EVENT_AUTH_DENIED,
49 EVENT_AUTH_GRANTED, 50 EVENT_AUTH_GRANTED,
50 EVENT_CLOSE, 51 EVENT_CLOSE,
51 EVENT_LISTEN, 52 EVENT_LISTEN,
52 EVENT_READ, 53 EVENT_READ,
53 }; 54 };
54 55
56 // TODO(byungchul): Use ScopedTempDir not to interfere other unittests with
57 // same socket path when multiple unittests are running in parallel.
55 string MakeSocketPath(const string& socket_file_name) { 58 string MakeSocketPath(const string& socket_file_name) {
56 base::FilePath temp_dir; 59 base::FilePath temp_dir;
57 base::GetTempDir(&temp_dir); 60 base::GetTempDir(&temp_dir);
58 return temp_dir.Append(socket_file_name).value(); 61 return temp_dir.Append(socket_file_name).value();
59 } 62 }
60 63
61 string MakeSocketPath() { 64 string MakeSocketPath() {
62 return MakeSocketPath(kSocketFilename); 65 return MakeSocketPath(kSocketFilename);
63 } 66 }
64 67
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 }; 147 };
145 148
146 bool UserCanConnectCallback( 149 bool UserCanConnectCallback(
147 bool allow_user, const scoped_refptr<EventManager>& event_manager, 150 bool allow_user, const scoped_refptr<EventManager>& event_manager,
148 uid_t, gid_t) { 151 uid_t, gid_t) {
149 event_manager->Notify( 152 event_manager->Notify(
150 allow_user ? EVENT_AUTH_GRANTED : EVENT_AUTH_DENIED); 153 allow_user ? EVENT_AUTH_GRANTED : EVENT_AUTH_DENIED);
151 return allow_user; 154 return allow_user;
152 } 155 }
153 156
154 class UnixDomainSocketTestHelper : public testing::Test { 157 class UnixDomainListenSocketTestHelper : public testing::Test {
155 public: 158 public:
156 void CreateAndListen() { 159 void CreateAndListen() {
157 socket_ = UnixDomainSocket::CreateAndListen( 160 socket_ = UnixDomainListenSocket::CreateAndListen(
158 file_path_.value(), socket_delegate_.get(), MakeAuthCallback()); 161 file_path_.value(), socket_delegate_.get(), MakeAuthCallback());
159 socket_delegate_->OnListenCompleted(); 162 socket_delegate_->OnListenCompleted();
160 } 163 }
161 164
162 protected: 165 protected:
163 UnixDomainSocketTestHelper(const string& path, bool allow_user) 166 UnixDomainListenSocketTestHelper(const string& path, bool allow_user)
164 : file_path_(path), 167 : file_path_(path),
165 allow_user_(allow_user) {} 168 allow_user_(allow_user) {}
166 169
167 virtual void SetUp() OVERRIDE { 170 virtual void SetUp() OVERRIDE {
168 event_manager_ = new EventManager(); 171 event_manager_ = new EventManager();
169 socket_delegate_.reset(new TestListenSocketDelegate(event_manager_)); 172 socket_delegate_.reset(new TestListenSocketDelegate(event_manager_));
170 DeleteSocketFile(); 173 DeleteSocketFile();
171 } 174 }
172 175
173 virtual void TearDown() OVERRIDE { 176 virtual void TearDown() OVERRIDE {
174 DeleteSocketFile(); 177 DeleteSocketFile();
175 socket_.reset(); 178 socket_.reset();
176 socket_delegate_.reset(); 179 socket_delegate_.reset();
177 event_manager_ = NULL; 180 event_manager_ = NULL;
178 } 181 }
179 182
180 UnixDomainSocket::AuthCallback MakeAuthCallback() { 183 UnixDomainListenSocket::AuthCallback MakeAuthCallback() {
181 return base::Bind(&UserCanConnectCallback, allow_user_, event_manager_); 184 return base::Bind(&UserCanConnectCallback, allow_user_, event_manager_);
182 } 185 }
183 186
184 void DeleteSocketFile() { 187 void DeleteSocketFile() {
185 ASSERT_FALSE(file_path_.empty()); 188 ASSERT_FALSE(file_path_.empty());
186 base::DeleteFile(file_path_, false /* not recursive */); 189 base::DeleteFile(file_path_, false /* not recursive */);
187 } 190 }
188 191
189 SocketDescriptor CreateClientSocket() { 192 SocketDescriptor CreateClientSocket() {
190 const SocketDescriptor sock = CreatePlatformSocket(PF_UNIX, SOCK_STREAM, 0); 193 const SocketDescriptor sock = CreatePlatformSocket(PF_UNIX, SOCK_STREAM, 0);
(...skipping 14 matching lines...) Expand all
205 return sock; 208 return sock;
206 } 209 }
207 210
208 scoped_ptr<base::Thread> CreateAndRunServerThread() { 211 scoped_ptr<base::Thread> CreateAndRunServerThread() {
209 base::Thread::Options options; 212 base::Thread::Options options;
210 options.message_loop_type = base::MessageLoop::TYPE_IO; 213 options.message_loop_type = base::MessageLoop::TYPE_IO;
211 scoped_ptr<base::Thread> thread(new base::Thread("socketio_test")); 214 scoped_ptr<base::Thread> thread(new base::Thread("socketio_test"));
212 thread->StartWithOptions(options); 215 thread->StartWithOptions(options);
213 thread->message_loop()->PostTask( 216 thread->message_loop()->PostTask(
214 FROM_HERE, 217 FROM_HERE,
215 base::Bind(&UnixDomainSocketTestHelper::CreateAndListen, 218 base::Bind(&UnixDomainListenSocketTestHelper::CreateAndListen,
216 base::Unretained(this))); 219 base::Unretained(this)));
217 return thread.Pass(); 220 return thread.Pass();
218 } 221 }
219 222
220 const base::FilePath file_path_; 223 const base::FilePath file_path_;
221 const bool allow_user_; 224 const bool allow_user_;
222 scoped_refptr<EventManager> event_manager_; 225 scoped_refptr<EventManager> event_manager_;
223 scoped_ptr<TestListenSocketDelegate> socket_delegate_; 226 scoped_ptr<TestListenSocketDelegate> socket_delegate_;
224 scoped_ptr<UnixDomainSocket> socket_; 227 scoped_ptr<UnixDomainListenSocket> socket_;
225 }; 228 };
226 229
227 class UnixDomainSocketTest : public UnixDomainSocketTestHelper { 230 class UnixDomainListenSocketTest : public UnixDomainListenSocketTestHelper {
228 protected: 231 protected:
229 UnixDomainSocketTest() 232 UnixDomainListenSocketTest()
230 : UnixDomainSocketTestHelper(MakeSocketPath(), true /* allow user */) {} 233 : UnixDomainListenSocketTestHelper(MakeSocketPath(),
234 true /* allow user */) {}
231 }; 235 };
232 236
233 class UnixDomainSocketTestWithInvalidPath : public UnixDomainSocketTestHelper { 237 class UnixDomainListenSocketTestWithInvalidPath
238 : public UnixDomainListenSocketTestHelper {
234 protected: 239 protected:
235 UnixDomainSocketTestWithInvalidPath() 240 UnixDomainListenSocketTestWithInvalidPath()
236 : UnixDomainSocketTestHelper(kInvalidSocketPath, true) {} 241 : UnixDomainListenSocketTestHelper(kInvalidSocketPath, true) {}
237 }; 242 };
238 243
239 class UnixDomainSocketTestWithForbiddenUser 244 class UnixDomainListenSocketTestWithForbiddenUser
240 : public UnixDomainSocketTestHelper { 245 : public UnixDomainListenSocketTestHelper {
241 protected: 246 protected:
242 UnixDomainSocketTestWithForbiddenUser() 247 UnixDomainListenSocketTestWithForbiddenUser()
243 : UnixDomainSocketTestHelper(MakeSocketPath(), false /* forbid user */) {} 248 : UnixDomainListenSocketTestHelper(MakeSocketPath(),
249 false /* forbid user */) {}
244 }; 250 };
245 251
246 TEST_F(UnixDomainSocketTest, CreateAndListen) { 252 TEST_F(UnixDomainListenSocketTest, CreateAndListen) {
247 CreateAndListen(); 253 CreateAndListen();
248 EXPECT_FALSE(socket_.get() == NULL); 254 EXPECT_FALSE(socket_.get() == NULL);
249 } 255 }
250 256
251 TEST_F(UnixDomainSocketTestWithInvalidPath, CreateAndListenWithInvalidPath) { 257 TEST_F(UnixDomainListenSocketTestWithInvalidPath,
258 CreateAndListenWithInvalidPath) {
252 CreateAndListen(); 259 CreateAndListen();
253 EXPECT_TRUE(socket_.get() == NULL); 260 EXPECT_TRUE(socket_.get() == NULL);
254 } 261 }
255 262
256 #ifdef SOCKET_ABSTRACT_NAMESPACE_SUPPORTED 263 #ifdef SOCKET_ABSTRACT_NAMESPACE_SUPPORTED
257 // Test with an invalid path to make sure that the socket is not backed by a 264 // Test with an invalid path to make sure that the socket is not backed by a
258 // file. 265 // file.
259 TEST_F(UnixDomainSocketTestWithInvalidPath, 266 TEST_F(UnixDomainListenSocketTestWithInvalidPath,
260 CreateAndListenWithAbstractNamespace) { 267 CreateAndListenWithAbstractNamespace) {
261 socket_ = UnixDomainSocket::CreateAndListenWithAbstractNamespace( 268 socket_ = UnixDomainListenSocket::CreateAndListenWithAbstractNamespace(
262 file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback()); 269 file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback());
263 EXPECT_FALSE(socket_.get() == NULL); 270 EXPECT_FALSE(socket_.get() == NULL);
264 } 271 }
265 272
266 TEST_F(UnixDomainSocketTest, TestFallbackName) { 273 TEST_F(UnixDomainListenSocketTest, TestFallbackName) {
267 scoped_ptr<UnixDomainSocket> existing_socket = 274 scoped_ptr<UnixDomainListenSocket> existing_socket =
268 UnixDomainSocket::CreateAndListenWithAbstractNamespace( 275 UnixDomainListenSocket::CreateAndListenWithAbstractNamespace(
269 file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback()); 276 file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback());
270 EXPECT_FALSE(existing_socket.get() == NULL); 277 EXPECT_FALSE(existing_socket.get() == NULL);
271 // First, try to bind socket with the same name with no fallback name. 278 // First, try to bind socket with the same name with no fallback name.
272 socket_ = 279 socket_ =
273 UnixDomainSocket::CreateAndListenWithAbstractNamespace( 280 UnixDomainListenSocket::CreateAndListenWithAbstractNamespace(
274 file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback()); 281 file_path_.value(), "", socket_delegate_.get(), MakeAuthCallback());
275 EXPECT_TRUE(socket_.get() == NULL); 282 EXPECT_TRUE(socket_.get() == NULL);
276 // Now with a fallback name. 283 // Now with a fallback name.
277 const char kFallbackSocketName[] = "unix_domain_socket_for_testing_2"; 284 const char kFallbackSocketName[] = "unix_domain_socket_for_testing_2";
278 socket_ = UnixDomainSocket::CreateAndListenWithAbstractNamespace( 285 socket_ = UnixDomainListenSocket::CreateAndListenWithAbstractNamespace(
279 file_path_.value(), 286 file_path_.value(),
280 MakeSocketPath(kFallbackSocketName), 287 MakeSocketPath(kFallbackSocketName),
281 socket_delegate_.get(), 288 socket_delegate_.get(),
282 MakeAuthCallback()); 289 MakeAuthCallback());
283 EXPECT_FALSE(socket_.get() == NULL); 290 EXPECT_FALSE(socket_.get() == NULL);
284 } 291 }
285 #endif 292 #endif
286 293
287 TEST_F(UnixDomainSocketTest, TestWithClient) { 294 TEST_F(UnixDomainListenSocketTest, TestWithClient) {
288 const scoped_ptr<base::Thread> server_thread = CreateAndRunServerThread(); 295 const scoped_ptr<base::Thread> server_thread = CreateAndRunServerThread();
289 EventType event = event_manager_->WaitForEvent(); 296 EventType event = event_manager_->WaitForEvent();
290 ASSERT_EQ(EVENT_LISTEN, event); 297 ASSERT_EQ(EVENT_LISTEN, event);
291 298
292 // Create the client socket. 299 // Create the client socket.
293 const SocketDescriptor sock = CreateClientSocket(); 300 const SocketDescriptor sock = CreateClientSocket();
294 ASSERT_NE(kInvalidSocket, sock); 301 ASSERT_NE(kInvalidSocket, sock);
295 event = event_manager_->WaitForEvent(); 302 event = event_manager_->WaitForEvent();
296 ASSERT_EQ(EVENT_AUTH_GRANTED, event); 303 ASSERT_EQ(EVENT_AUTH_GRANTED, event);
297 event = event_manager_->WaitForEvent(); 304 event = event_manager_->WaitForEvent();
298 ASSERT_EQ(EVENT_ACCEPT, event); 305 ASSERT_EQ(EVENT_ACCEPT, event);
299 306
300 // Send a message from the client to the server. 307 // Send a message from the client to the server.
301 ssize_t ret = HANDLE_EINTR(send(sock, kMsg, sizeof(kMsg), 0)); 308 ssize_t ret = HANDLE_EINTR(send(sock, kMsg, sizeof(kMsg), 0));
302 ASSERT_NE(-1, ret); 309 ASSERT_NE(-1, ret);
303 ASSERT_EQ(sizeof(kMsg), static_cast<size_t>(ret)); 310 ASSERT_EQ(sizeof(kMsg), static_cast<size_t>(ret));
304 event = event_manager_->WaitForEvent(); 311 event = event_manager_->WaitForEvent();
305 ASSERT_EQ(EVENT_READ, event); 312 ASSERT_EQ(EVENT_READ, event);
306 ASSERT_EQ(kMsg, socket_delegate_->ReceivedData()); 313 ASSERT_EQ(kMsg, socket_delegate_->ReceivedData());
307 314
308 // Close the client socket. 315 // Close the client socket.
309 ret = IGNORE_EINTR(close(sock)); 316 ret = IGNORE_EINTR(close(sock));
310 event = event_manager_->WaitForEvent(); 317 event = event_manager_->WaitForEvent();
311 ASSERT_EQ(EVENT_CLOSE, event); 318 ASSERT_EQ(EVENT_CLOSE, event);
312 } 319 }
313 320
314 TEST_F(UnixDomainSocketTestWithForbiddenUser, TestWithForbiddenUser) { 321 TEST_F(UnixDomainListenSocketTestWithForbiddenUser, TestWithForbiddenUser) {
315 const scoped_ptr<base::Thread> server_thread = CreateAndRunServerThread(); 322 const scoped_ptr<base::Thread> server_thread = CreateAndRunServerThread();
316 EventType event = event_manager_->WaitForEvent(); 323 EventType event = event_manager_->WaitForEvent();
317 ASSERT_EQ(EVENT_LISTEN, event); 324 ASSERT_EQ(EVENT_LISTEN, event);
318 const SocketDescriptor sock = CreateClientSocket(); 325 const SocketDescriptor sock = CreateClientSocket();
319 ASSERT_NE(kInvalidSocket, sock); 326 ASSERT_NE(kInvalidSocket, sock);
320 327
321 event = event_manager_->WaitForEvent(); 328 event = event_manager_->WaitForEvent();
322 ASSERT_EQ(EVENT_AUTH_DENIED, event); 329 ASSERT_EQ(EVENT_AUTH_DENIED, event);
323 330
324 // Wait until the file descriptor is closed by the server. 331 // Wait until the file descriptor is closed by the server.
325 struct pollfd poll_fd; 332 struct pollfd poll_fd;
326 poll_fd.fd = sock; 333 poll_fd.fd = sock;
327 poll_fd.events = POLLIN; 334 poll_fd.events = POLLIN;
328 poll(&poll_fd, 1, -1 /* rely on GTest for timeout handling */); 335 poll(&poll_fd, 1, -1 /* rely on GTest for timeout handling */);
329 336
330 // Send() must fail. 337 // Send() must fail.
331 ssize_t ret = HANDLE_EINTR(send(sock, kMsg, sizeof(kMsg), 0)); 338 ssize_t ret = HANDLE_EINTR(send(sock, kMsg, sizeof(kMsg), 0));
332 ASSERT_EQ(-1, ret); 339 ASSERT_EQ(-1, ret);
333 ASSERT_EQ(EPIPE, errno); 340 ASSERT_EQ(EPIPE, errno);
334 ASSERT_FALSE(event_manager_->HasPendingEvent()); 341 ASSERT_FALSE(event_manager_->HasPendingEvent());
335 } 342 }
336 343
337 } // namespace 344 } // namespace
338 } // namespace net 345 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698