1 // Copyright 2015 The Chromium OS 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 <brillo/message_loops/glib_message_loop.h>
6
7 #include <fcntl.h>
8 #include <unistd.h>
9
10 #include <memory>
11
12 #include <base/bind.h>
13 #include <base/location.h>
14 #include <base/posix/eintr_wrapper.h>
15 #include <gtest/gtest.h>
16
17 #include <brillo/bind_lambda.h>
18 #include <brillo/message_loops/message_loop.h>
19 #include <brillo/message_loops/message_loop_utils.h>
20
21 using base::Bind;
22
23 namespace brillo {
24
25 using TaskId = MessageLoop::TaskId;
26
27 class GlibMessageLoopTest : public ::testing::Test {
28 protected:
SetUp()29 void SetUp() override {
30 loop_.reset(new GlibMessageLoop());
31 EXPECT_TRUE(loop_.get());
32 }
33
34 std::unique_ptr<GlibMessageLoop> loop_;
35 };
36
37 // When you watch a file descriptor for reading, the guaranties are that a
38 // blocking call to read() on that file descriptor will not block. This should
39 // include the case when the other end of a pipe is closed or the file is empty.
TEST_F(GlibMessageLoopTest,WatchFileDescriptorTriggersWhenEmpty)40 TEST_F(GlibMessageLoopTest, WatchFileDescriptorTriggersWhenEmpty) {
41 int fd = HANDLE_EINTR(open("/dev/null", O_RDONLY));
42 int called = 0;
43 TaskId task_id = loop_->WatchFileDescriptor(
44 FROM_HERE, fd, MessageLoop::kWatchRead, true,
45 Bind([&called] { called++; }));
46 EXPECT_NE(MessageLoop::kTaskIdNull, task_id);
47 EXPECT_NE(0, MessageLoopRunMaxIterations(loop_.get(), 10));
48 EXPECT_LT(2, called);
49 EXPECT_TRUE(loop_->CancelTask(task_id));
50 }
51
52 // Test that an invalid file descriptor triggers the callback.
TEST_F(GlibMessageLoopTest,WatchFileDescriptorTriggersWhenInvalid)53 TEST_F(GlibMessageLoopTest, WatchFileDescriptorTriggersWhenInvalid) {
54 int fd = HANDLE_EINTR(open("/dev/zero", O_RDONLY));
55 int called = 0;
56 TaskId task_id = loop_->WatchFileDescriptor(
57 FROM_HERE, fd, MessageLoop::kWatchRead, true,
58 Bind([&called, fd] {
59 if (!called)
60 IGNORE_EINTR(close(fd));
61 called++;
62 }));
63 EXPECT_NE(MessageLoop::kTaskIdNull, task_id);
64 EXPECT_NE(0, MessageLoopRunMaxIterations(loop_.get(), 10));
65 EXPECT_LT(2, called);
66 EXPECT_TRUE(loop_->CancelTask(task_id));
67 }
68
69 } // namespace brillo
70