blob: c3ec97e3a3fc0c6e5d4cf7aee1a93b3fef2fdfc6 [file] [log] [blame]
[email protected]8c3881ab2012-01-04 19:02:381// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]b4339c3a2011-05-13 16:19:232// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/message_pump_libevent.h"
6
7#include <unistd.h>
8
9#include "base/message_loop.h"
10#include "base/threading/thread.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
[email protected]8d5f3ac2011-07-20 16:01:3213#if defined(USE_SYSTEM_LIBEVENT)
14#include <event.h>
15#else
16#include "third_party/libevent/event.h"
17#endif
18
19namespace base {
[email protected]b4339c3a2011-05-13 16:19:2320
21class MessagePumpLibeventTest : public testing::Test {
[email protected]8d5f3ac2011-07-20 16:01:3222 protected:
[email protected]b4339c3a2011-05-13 16:19:2323 MessagePumpLibeventTest()
24 : ui_loop_(MessageLoop::TYPE_UI),
25 io_thread_("MessagePumpLibeventTestIOThread") {}
26 virtual ~MessagePumpLibeventTest() {}
27
28 virtual void SetUp() {
[email protected]8d5f3ac2011-07-20 16:01:3229 Thread::Options options(MessageLoop::TYPE_IO, 0);
[email protected]b4339c3a2011-05-13 16:19:2330 ASSERT_TRUE(io_thread_.StartWithOptions(options));
31 ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type());
32 }
33
34 MessageLoop* ui_loop() { return &ui_loop_; }
35 MessageLoopForIO* io_loop() const {
36 return static_cast<MessageLoopForIO*>(io_thread_.message_loop());
37 }
38
[email protected]8d5f3ac2011-07-20 16:01:3239 void OnLibeventNotification(
40 MessagePumpLibevent* pump,
41 MessagePumpLibevent::FileDescriptorWatcher* controller) {
42 pump->OnLibeventNotification(0, EV_WRITE | EV_READ, controller);
43 }
44
[email protected]b4339c3a2011-05-13 16:19:2345 MessageLoop ui_loop_;
[email protected]8d5f3ac2011-07-20 16:01:3246 Thread io_thread_;
[email protected]b4339c3a2011-05-13 16:19:2347};
48
[email protected]8d5f3ac2011-07-20 16:01:3249namespace {
50
51// Concrete implementation of MessagePumpLibevent::Watcher that does
[email protected]b4339c3a2011-05-13 16:19:2352// nothing useful.
[email protected]8d5f3ac2011-07-20 16:01:3253class StupidWatcher : public MessagePumpLibevent::Watcher {
[email protected]b4339c3a2011-05-13 16:19:2354 public:
55 virtual ~StupidWatcher() {}
56
[email protected]a27de262011-06-22 06:33:0557 // base:MessagePumpLibevent::Watcher interface
[email protected]b4339c3a2011-05-13 16:19:2358 virtual void OnFileCanReadWithoutBlocking(int fd) {}
59 virtual void OnFileCanWriteWithoutBlocking(int fd) {}
60};
61
[email protected]8c3881ab2012-01-04 19:02:3862#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]b4339c3a2011-05-13 16:19:2363
64// Test to make sure that we catch calling WatchFileDescriptor off of the
65// wrong thread.
66TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) {
[email protected]8d5f3ac2011-07-20 16:01:3267 MessagePumpLibevent::FileDescriptorWatcher watcher;
[email protected]b4339c3a2011-05-13 16:19:2368 StupidWatcher delegate;
69
[email protected]8c3881ab2012-01-04 19:02:3870 ASSERT_DEATH(io_loop()->WatchFileDescriptor(
[email protected]b4339c3a2011-05-13 16:19:2371 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
72 "Check failed: "
73 "watch_file_descriptor_caller_checker_.CalledOnValidThread()");
74}
75
[email protected]8c3881ab2012-01-04 19:02:3876#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]8d5f3ac2011-07-20 16:01:3277
78class DeleteWatcher : public MessagePumpLibevent::Watcher {
79 public:
80 explicit DeleteWatcher(
81 MessagePumpLibevent::FileDescriptorWatcher* controller)
82 : controller_(controller) {
83 DCHECK(controller_);
84 }
85 virtual ~DeleteWatcher() {}
86
87 // base:MessagePumpLibevent::Watcher interface
88 virtual void OnFileCanReadWithoutBlocking(int /* fd */) {
89 NOTREACHED();
90 }
91 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {
92 delete controller_;
93 }
94
95 private:
96 MessagePumpLibevent::FileDescriptorWatcher* const controller_;
97};
98
99TEST_F(MessagePumpLibeventTest, DeleteWatcher) {
100 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
101 MessagePumpLibevent::FileDescriptorWatcher* watcher =
102 new MessagePumpLibevent::FileDescriptorWatcher;
103 DeleteWatcher delegate(watcher);
104 pump->WatchFileDescriptor(
105 0, false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate);
106
107 // Spoof a libevent notification.
108 OnLibeventNotification(pump, watcher);
109}
110
111class StopWatcher : public MessagePumpLibevent::Watcher {
112 public:
113 explicit StopWatcher(
114 MessagePumpLibevent::FileDescriptorWatcher* controller)
115 : controller_(controller) {
116 DCHECK(controller_);
117 }
118 virtual ~StopWatcher() {}
119
120 // base:MessagePumpLibevent::Watcher interface
121 virtual void OnFileCanReadWithoutBlocking(int /* fd */) {
122 NOTREACHED();
123 }
124 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {
125 controller_->StopWatchingFileDescriptor();
126 }
127
128 private:
129 MessagePumpLibevent::FileDescriptorWatcher* const controller_;
130};
131
132TEST_F(MessagePumpLibeventTest, StopWatcher) {
133 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
134 MessagePumpLibevent::FileDescriptorWatcher watcher;
135 StopWatcher delegate(&watcher);
136 pump->WatchFileDescriptor(
137 0, false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate);
138
139 // Spoof a libevent notification.
140 OnLibeventNotification(pump, &watcher);
141}
142
143} // namespace
144
145} // namespace base