blob: 8da9a342cc447e58887c26947d4d362efc3dde76 [file] [log] [blame]
// Copyright 2012 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 "base/message_loop/message_pump_io_ios.h"
#include <unistd.h>
#include "base/macros.h"
#include "base/posix/eintr_wrapper.h"
#include "base/test/gtest_util.h"
#include "base/threading/thread.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
class MessagePumpIOSForIOTest : public testing::Test {
protected:
MessagePumpIOSForIOTest() = default;
~MessagePumpIOSForIOTest() override = default;
void SetUp() override {
int ret = pipe(pipefds_);
ASSERT_EQ(0, ret);
ret = pipe(alternate_pipefds_);
ASSERT_EQ(0, ret);
}
void TearDown() override {
if (IGNORE_EINTR(close(pipefds_[0])) < 0)
PLOG(ERROR) << "close";
if (IGNORE_EINTR(close(pipefds_[1])) < 0)
PLOG(ERROR) << "close";
}
void HandleFdIOEvent(MessagePumpForIO::FdWatchController* watcher) {
MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_.get(),
kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack,
watcher);
}
int pipefds_[2];
int alternate_pipefds_[2];
private:
DISALLOW_COPY_AND_ASSIGN(MessagePumpIOSForIOTest);
};
namespace {
// Concrete implementation of MessagePumpIOSForIO::FdWatcher that does
// nothing useful.
class StupidWatcher : public MessagePumpIOSForIO::FdWatcher {
public:
~StupidWatcher() override {}
// base:MessagePumpIOSForIO::FdWatcher interface
void OnFileCanReadWithoutBlocking(int fd) override {}
void OnFileCanWriteWithoutBlocking(int fd) override {}
};
class BaseWatcher : public MessagePumpIOSForIO::FdWatcher {
public:
BaseWatcher(MessagePumpIOSForIO::FdWatchController* controller)
: controller_(controller) {
DCHECK(controller_);
}
~BaseWatcher() override {}
// MessagePumpIOSForIO::FdWatcher interface
void OnFileCanReadWithoutBlocking(int fd) override { NOTREACHED(); }
void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
protected:
MessagePumpIOSForIO::FdWatchController* controller_;
};
class DeleteWatcher : public BaseWatcher {
public:
explicit DeleteWatcher(MessagePumpIOSForIO::FdWatchController* controller)
: BaseWatcher(controller) {}
~DeleteWatcher() override { DCHECK(!controller_); }
void OnFileCanWriteWithoutBlocking(int fd) override {
DCHECK(controller_);
delete controller_;
controller_ = NULL;
}
};
TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
MessagePumpIOSForIO::FdWatchController* watcher =
new MessagePumpIOSForIO::FdWatchController(FROM_HERE);
DeleteWatcher delegate(watcher);
pump->WatchFileDescriptor(pipefds_[1],
false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate);
// Spoof a callback.
HandleFdIOEvent(watcher);
}
class StopWatcher : public BaseWatcher {
public:
StopWatcher(MessagePumpIOSForIO::FdWatchController* controller,
MessagePumpIOSForIO* pump,
int fd_to_start_watching = -1)
: BaseWatcher(controller),
pump_(pump),
fd_to_start_watching_(fd_to_start_watching) {}
~StopWatcher() override {}
void OnFileCanWriteWithoutBlocking(int fd) override {
controller_->StopWatchingFileDescriptor();
if (fd_to_start_watching_ >= 0) {
pump_->WatchFileDescriptor(fd_to_start_watching_,
false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this);
}
}
private:
MessagePumpIOSForIO* pump_;
int fd_to_start_watching_;
};
TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
StopWatcher delegate(&watcher, pump.get());
pump->WatchFileDescriptor(pipefds_[1],
false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
// Spoof a callback.
HandleFdIOEvent(&watcher);
}
TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
StopWatcher delegate(&watcher, pump.get(), alternate_pipefds_[1]);
pump->WatchFileDescriptor(pipefds_[1],
false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
// Spoof a callback.
HandleFdIOEvent(&watcher);
}
} // namespace
} // namespace base