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

Unified 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: un-revert fix to tests 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ipc/unix_domain_socket_util.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ipc/unix_domain_socket_util_unittest.cc
diff --git a/ipc/unix_domain_socket_util_unittest.cc b/ipc/unix_domain_socket_util_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a00d3aae4837f80c1201f030889c3ef9ebad0c0a
--- /dev/null
+++ b/ipc/unix_domain_socket_util_unittest.cc
@@ -0,0 +1,179 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <sys/socket.h>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_restrictions.h"
+#include "ipc/unix_domain_socket_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class SocketAcceptor : public MessageLoopForIO::Watcher {
+ public:
+ SocketAcceptor(int fd, base::MessageLoopProxy* target_thread)
+ : server_fd_(-1),
+ target_thread_(target_thread),
+ started_watching_event_(false, false),
+ accepted_event_(false, false) {
+ target_thread->PostTask(FROM_HERE,
+ base::Bind(&SocketAcceptor::StartWatching, base::Unretained(this), fd));
+ }
+
+ virtual ~SocketAcceptor() {
+ Close();
+ }
+
+ int server_fd() const { return server_fd_; }
+
+ void WaitUntilReady() {
+ started_watching_event_.Wait();
+ }
+
+ void WaitForAccept() {
+ accepted_event_.Wait();
+ }
+
+ void Close() {
+ if (watcher_.get()) {
+ target_thread_->PostTask(FROM_HERE,
+ base::Bind(&SocketAcceptor::StopWatching, base::Unretained(this),
+ watcher_.release()));
+ }
+ }
+
+ private:
+ void StartWatching(int fd) {
+ watcher_.reset(new MessageLoopForIO::FileDescriptorWatcher);
+ MessageLoopForIO::current()->WatchFileDescriptor(
+ fd,
+ true,
+ MessageLoopForIO::WATCH_READ,
+ watcher_.get(),
+ this);
+ started_watching_event_.Signal();
+ }
+ void StopWatching(MessageLoopForIO::FileDescriptorWatcher* watcher) {
+ watcher->StopWatchingFileDescriptor();
+ delete watcher;
+ }
+ virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
+ ASSERT_EQ(-1, server_fd_);
+ IPC::ServerAcceptConnection(fd, &server_fd_);
+ watcher_->StopWatchingFileDescriptor();
+ accepted_event_.Signal();
+ }
+ virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
+
+ int server_fd_;
+ base::MessageLoopProxy* target_thread_;
+ scoped_ptr<MessageLoopForIO::FileDescriptorWatcher> watcher_;
+ base::WaitableEvent started_watching_event_;
+ base::WaitableEvent accepted_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(SocketAcceptor);
+};
+
+const base::FilePath GetChannelDir() {
+#if defined(OS_ANDROID)
+ base::FilePath tmp_dir;
+ PathService::Get(base::DIR_CACHE, &tmp_dir);
+ return tmp_dir;
+#else
+ return base::FilePath("/var/tmp");
+#endif
+}
+
+class TestUnixSocketConnection {
+ public:
+ TestUnixSocketConnection()
+ : worker_("WorkerThread"),
+ server_listen_fd_(-1),
+ server_fd_(-1),
+ client_fd_(-1) {
+ socket_name_ = GetChannelDir().Append("TestSocket");
+ base::Thread::Options options;
+ options.message_loop_type = MessageLoop::TYPE_IO;
+ worker_.StartWithOptions(options);
+ }
+
+ bool CreateServerSocket() {
+ IPC::CreateServerUnixDomainSocket(socket_name_, &server_listen_fd_);
+ if (server_listen_fd_ < 0)
+ return false;
+ struct stat socket_stat;
+ stat(socket_name_.value().c_str(), &socket_stat);
+ EXPECT_TRUE(S_ISSOCK(socket_stat.st_mode));
+ acceptor_.reset(new SocketAcceptor(server_listen_fd_,
+ worker_.message_loop_proxy()));
+ acceptor_->WaitUntilReady();
+ return true;
+ }
+
+ bool CreateClientSocket() {
+ DCHECK(server_listen_fd_ >= 0);
+ IPC::CreateClientUnixDomainSocket(socket_name_, &client_fd_);
+ if (client_fd_ < 0)
+ return false;
+ acceptor_->WaitForAccept();
+ server_fd_ = acceptor_->server_fd();
+ return server_fd_ >= 0;
+ }
+
+ virtual ~TestUnixSocketConnection() {
+ if (client_fd_ >= 0)
+ close(client_fd_);
+ if (server_fd_ >= 0)
+ close(server_fd_);
+ if (server_listen_fd_ >= 0) {
+ close(server_listen_fd_);
+ unlink(socket_name_.value().c_str());
+ }
+ }
+
+ int client_fd() const { return client_fd_; }
+ int server_fd() const { return server_fd_; }
+
+ private:
+ base::Thread worker_;
+ base::FilePath socket_name_;
+ int server_listen_fd_;
+ int server_fd_;
+ int client_fd_;
+ scoped_ptr<SocketAcceptor> acceptor_;
+};
+
+// Ensure that IPC::CreateServerUnixDomainSocket creates a socket that
+// IPC::CreateClientUnixDomainSocket can successfully connect to.
+TEST(UnixDomainSocketUtil, Connect) {
+ TestUnixSocketConnection connection;
+ ASSERT_TRUE(connection.CreateServerSocket());
+ ASSERT_TRUE(connection.CreateClientSocket());
+}
+
+// Ensure that messages can be sent across the resulting socket.
+TEST(UnixDomainSocketUtil, SendReceive) {
+ TestUnixSocketConnection connection;
+ ASSERT_TRUE(connection.CreateServerSocket());
+ ASSERT_TRUE(connection.CreateClientSocket());
+
+ const char buffer[] = "Hello, server!";
+ size_t buf_len = sizeof(buffer);
+ size_t sent_bytes =
+ HANDLE_EINTR(send(connection.client_fd(), buffer, buf_len, 0));
+ ASSERT_EQ(buf_len, sent_bytes);
+ char recv_buf[sizeof(buffer)];
+ size_t received_bytes =
+ HANDLE_EINTR(recv(connection.server_fd(), recv_buf, buf_len, 0));
+ ASSERT_EQ(buf_len, received_bytes);
+ ASSERT_EQ(0, memcmp(recv_buf, buffer, buf_len));
+}
+
+} // namespace
« no previous file with comments | « ipc/unix_domain_socket_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698