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