xref: /aosp_15_r20/external/cronet/base/message_loop/message_pump_io_ios_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
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 "base/message_loop/message_pump_io_ios.h"
6 
7 #include <unistd.h>
8 
9 #include "base/logging.h"
10 #include "base/message_loop/message_pump_for_io.h"
11 #include "base/posix/eintr_wrapper.h"
12 #include "base/test/gtest_util.h"
13 #include "base/threading/thread.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 namespace base {
17 
18 class MessagePumpIOSForIOTest : public testing::Test {
19  public:
20   MessagePumpIOSForIOTest(const MessagePumpIOSForIOTest&) = delete;
21   MessagePumpIOSForIOTest& operator=(const MessagePumpIOSForIOTest&) = delete;
22 
23  protected:
24   MessagePumpIOSForIOTest() = default;
25   ~MessagePumpIOSForIOTest() override = default;
26 
SetUp()27   void SetUp() override {
28     int ret = pipe(pipefds_);
29     ASSERT_EQ(0, ret);
30     ret = pipe(alternate_pipefds_);
31     ASSERT_EQ(0, ret);
32   }
33 
TearDown()34   void TearDown() override {
35     if (IGNORE_EINTR(close(pipefds_[0])) < 0)
36       PLOG(ERROR) << "close";
37     if (IGNORE_EINTR(close(pipefds_[1])) < 0)
38       PLOG(ERROR) << "close";
39   }
40 
HandleFdIOEvent(MessagePumpForIO::FdWatchController * watcher)41   void HandleFdIOEvent(MessagePumpForIO::FdWatchController* watcher) {
42     MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_.get(),
43         kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack,
44         watcher);
45   }
46 
47   int pipefds_[2];
48   int alternate_pipefds_[2];
49 };
50 
51 namespace {
52 
53 // Concrete implementation of MessagePumpIOSForIO::FdWatcher that does
54 // nothing useful.
55 class StupidWatcher : public MessagePumpIOSForIO::FdWatcher {
56  public:
~StupidWatcher()57   ~StupidWatcher() override {}
58 
59   // base:MessagePumpIOSForIO::FdWatcher interface
OnFileCanReadWithoutBlocking(int fd)60   void OnFileCanReadWithoutBlocking(int fd) override {}
OnFileCanWriteWithoutBlocking(int fd)61   void OnFileCanWriteWithoutBlocking(int fd) override {}
62 };
63 
64 class BaseWatcher : public MessagePumpIOSForIO::FdWatcher {
65  public:
BaseWatcher(MessagePumpIOSForIO::FdWatchController * controller)66   BaseWatcher(MessagePumpIOSForIO::FdWatchController* controller)
67       : controller_(controller) {
68     DCHECK(controller_);
69   }
~BaseWatcher()70   ~BaseWatcher() override {}
71 
72   // MessagePumpIOSForIO::FdWatcher interface
OnFileCanReadWithoutBlocking(int)73   void OnFileCanReadWithoutBlocking(int /* fd */) override { NOTREACHED(); }
74 
OnFileCanWriteWithoutBlocking(int)75   void OnFileCanWriteWithoutBlocking(int /* fd */) override { NOTREACHED(); }
76 
77  protected:
78   MessagePumpIOSForIO::FdWatchController* controller_;
79 };
80 
81 class DeleteWatcher : public BaseWatcher {
82  public:
DeleteWatcher(MessagePumpIOSForIO::FdWatchController * controller)83   explicit DeleteWatcher(MessagePumpIOSForIO::FdWatchController* controller)
84       : BaseWatcher(controller) {}
85 
~DeleteWatcher()86   ~DeleteWatcher() override { DCHECK(!controller_); }
87 
OnFileCanWriteWithoutBlocking(int)88   void OnFileCanWriteWithoutBlocking(int /* fd */) override {
89     DCHECK(controller_);
90     delete controller_;
91     controller_ = NULL;
92   }
93 };
94 
TEST_F(MessagePumpIOSForIOTest,DeleteWatcher)95 TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
96   std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
97   MessagePumpIOSForIO::FdWatchController* watcher =
98       new MessagePumpIOSForIO::FdWatchController(FROM_HERE);
99   DeleteWatcher delegate(watcher);
100   pump->WatchFileDescriptor(pipefds_[1],
101       false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate);
102 
103   // Spoof a callback.
104   HandleFdIOEvent(watcher);
105 }
106 
107 class StopWatcher : public BaseWatcher {
108  public:
StopWatcher(MessagePumpIOSForIO::FdWatchController * controller,MessagePumpIOSForIO * pump,int fd_to_start_watching=-1)109   StopWatcher(MessagePumpIOSForIO::FdWatchController* controller,
110               MessagePumpIOSForIO* pump,
111               int fd_to_start_watching = -1)
112       : BaseWatcher(controller),
113         pump_(pump),
114         fd_to_start_watching_(fd_to_start_watching) {}
115 
~StopWatcher()116   ~StopWatcher() override {}
117 
OnFileCanWriteWithoutBlocking(int)118   void OnFileCanWriteWithoutBlocking(int /* fd */) override {
119     controller_->StopWatchingFileDescriptor();
120     if (fd_to_start_watching_ >= 0) {
121       pump_->WatchFileDescriptor(fd_to_start_watching_,
122           false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this);
123     }
124   }
125 
126  private:
127   MessagePumpIOSForIO* pump_;
128   int fd_to_start_watching_;
129 };
130 
TEST_F(MessagePumpIOSForIOTest,StopWatcher)131 TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
132   std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
133   MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
134   StopWatcher delegate(&watcher, pump.get());
135   pump->WatchFileDescriptor(pipefds_[1],
136       false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
137 
138   // Spoof a callback.
139   HandleFdIOEvent(&watcher);
140 }
141 
TEST_F(MessagePumpIOSForIOTest,StopWatcherAndWatchSomethingElse)142 TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
143   std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
144   MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
145   StopWatcher delegate(&watcher, pump.get(), alternate_pipefds_[1]);
146   pump->WatchFileDescriptor(pipefds_[1],
147       false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
148 
149   // Spoof a callback.
150   HandleFdIOEvent(&watcher);
151 }
152 
153 }  // namespace
154 
155 }  // namespace base
156