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

Side by Side Diff: ipc/unix_domain_socket_util_unittest.cc

Issue 12386010: Implement IPC::ChannelFactory, a class that accept()s on a UNIX socket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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 <sys/socket.h>
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "ipc/unix_domain_socket_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 class SocketAcceptor : public MessageLoopForIO::Watcher {
19 public:
20 SocketAcceptor(int fd, base::MessageLoopProxy* target_thread)
21 : server_fd_(-1),
22 started_watching_event_(false, false),
23 accepted_event_(false, false) {
24 target_thread->PostTask(FROM_HERE,
25 base::Bind(&SocketAcceptor::StartWatching, base::Unretained(this), fd));
26 }
27
28 virtual ~SocketAcceptor() {
29 watcher_.StopWatchingFileDescriptor();
30 }
31
32 int server_fd() { return server_fd_; }
Mark Mentovai 2013/03/05 20:08:03 This method can be const, just for kicks.
jeremya 2013/03/06 05:03:18 Done.
33
34 void WaitUntilReady() {
35 started_watching_event_.Wait();
36 }
37 void WaitForAccept() {
38 accepted_event_.Wait();
39 }
40
41 private:
42 void StartWatching(int fd) {
43 MessageLoopForIO::current()->WatchFileDescriptor(
44 fd,
45 true,
46 MessageLoopForIO::WATCH_READ,
47 &watcher_,
48 this);
49 started_watching_event_.Signal();
50 }
51 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
52 ASSERT_EQ(-1, server_fd_);
53 IPC::ServerAcceptConnection(fd, &server_fd_);
54 watcher_.StopWatchingFileDescriptor();
55 accepted_event_.Signal();
56 }
57 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
58
59 int server_fd_;
60 MessageLoopForIO::FileDescriptorWatcher watcher_;
61 base::WaitableEvent started_watching_event_;
62 base::WaitableEvent accepted_event_;
63
64 DISALLOW_COPY_AND_ASSIGN(SocketAcceptor);
65 };
66
67 base::FilePath GetChannelDir() {
68 return base::FilePath("/var/tmp");
69 }
70
71 class TestUnixSocketConnection {
72 public:
73 TestUnixSocketConnection()
74 : worker_("WorkerThread"),
75 server_listen_fd_(-1),
76 server_fd_(-1),
77 client_fd_(-1),
78 acceptor_(NULL) {
79 socket_name_ = GetChannelDir().Append("TestSocket");
80 base::Thread::Options options;
81 options.message_loop_type = MessageLoop::TYPE_IO;
82 worker_.StartWithOptions(options);
83 }
84
85 bool CreateServerSocket() {
86 IPC::CreateServerUnixDomainSocket(socket_name_, &server_listen_fd_);
87 if (server_listen_fd_ < 0)
88 return false;
89 // TODO stat socket_name and check that there's a socket present
Mark Mentovai 2013/03/05 20:08:03 OK, so do this.
jeremya 2013/03/06 05:03:18 Done.
90 acceptor_ = new SocketAcceptor(server_listen_fd_,
91 worker_.message_loop_proxy());
92 acceptor_->WaitUntilReady();
93 return true;
94 }
95
96 bool CreateClientSocket() {
97 DCHECK(server_listen_fd_ >= 0);
98 IPC::CreateClientUnixDomainSocket(socket_name_, &client_fd_);
99 if (client_fd_ < 0)
100 return false;
101 acceptor_->WaitForAccept();
102 server_fd_ = acceptor_->server_fd();
103 return server_fd_ >= 0;
104 }
105
106 virtual ~TestUnixSocketConnection() {
107 if (acceptor_)
108 delete acceptor_;
109 if (client_fd_)
110 close(client_fd_);
111 if (server_fd_)
112 close(server_fd_);
113 if (server_listen_fd_) {
114 close(server_listen_fd_);
115 unlink(socket_name_.value().c_str());
116 }
117 }
118
119 int client_fd() { return client_fd_; }
120 int server_fd() { return server_fd_; }
121
122 private:
123 base::Thread worker_;
124 base::FilePath socket_name_;
125 int server_listen_fd_;
126 int server_fd_;
127 int client_fd_;
128 SocketAcceptor* acceptor_;
129 };
130
131 // Ensure that IPC::CreateServerUnixDomainSocket creates a socket that
132 // IPC::CreateClientUnixDomainSocket can successfully connect to.
133 TEST(UnixDomainSocketUtil, Connect) {
134 TestUnixSocketConnection connection;
135 ASSERT_TRUE(connection.CreateServerSocket());
136 ASSERT_TRUE(connection.CreateClientSocket());
137 }
138
139 // Ensure that messages can be sent across the resulting socket.
140 TEST(UnixDomainSocketUtil, SendReceive) {
141 TestUnixSocketConnection connection;
142 ASSERT_TRUE(connection.CreateServerSocket());
143 ASSERT_TRUE(connection.CreateClientSocket());
144
145 const char buffer[] = "Hello, server!";
146 size_t buf_len = strlen(buffer) + 1;
Mark Mentovai 2013/03/05 20:08:03 You could just use sizeof(buffer).
jeremya 2013/03/06 05:03:18 Done.
147 size_t sent_bytes = send(connection.client_fd(), buffer, buf_len, 0);
Mark Mentovai 2013/03/05 20:08:03 HANDLE_EINTR here and on line 151.
jeremya 2013/03/06 05:03:18 Done.
148 ASSERT_EQ(buf_len, sent_bytes);
149 scoped_array<char> recv_buf(new char[buf_len]);
Mark Mentovai 2013/03/05 20:08:03 You could just have a char recv_buf[sizeof(buffer)
jeremya 2013/03/06 05:03:18 Done.
150 size_t received_bytes =
151 recv(connection.server_fd(), recv_buf.get(), buf_len, 0);
152 ASSERT_EQ(buf_len, received_bytes);
153 ASSERT_EQ(0, strncmp(recv_buf.get(), buffer, buf_len));
Mark Mentovai 2013/03/05 20:08:03 Use memcmp. You have sizes in hand and you want to
jeremya 2013/03/06 05:03:18 Done.
154 }
155
156 }
Mark Mentovai 2013/03/05 20:08:03 } // namespace
jeremya 2013/03/06 05:03:18 Done.
OLDNEW
« ipc/unix_domain_socket_util.cc ('K') | « ipc/unix_domain_socket_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698