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
21using base::Bind;
22
23namespace brillo {
24
25using TaskId = MessageLoop::TaskId;
26
27class GlibMessageLoopTest : public ::testing::Test {
28 protected:
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.
40TEST_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.
53TEST_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