summaryrefslogtreecommitdiffstats
path: root/mojo/public/cpp/environment/tests/async_waiter_unittest.cc
blob: 1c1c2bf9d049fe521ad2726e82d0e2106c87d668 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/environment/async_waiter.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "mojo/public/cpp/utility/run_loop.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace {

class TestAsyncWaitCallback {
 public:
  TestAsyncWaitCallback() : result_count_(0), last_result_(MOJO_RESULT_OK) {}
  ~TestAsyncWaitCallback() {}

  int result_count() const { return result_count_; }

  MojoResult last_result() const { return last_result_; }

  void OnHandleReady(MojoResult result) {
    result_count_++;
    last_result_ = result;
  }

 private:
  int result_count_;
  MojoResult last_result_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(TestAsyncWaitCallback);
};

// Manual code to create a callback since we don't have mojo::Bind yet.
class ManualCallback {
 public:
  explicit ManualCallback(TestAsyncWaitCallback* callback)
      : callback_(callback) {}

  void Run(MojoResult result) const { callback_->OnHandleReady(result); }

 private:
  TestAsyncWaitCallback* callback_;
};

class AsyncWaiterTest : public testing::Test {
 public:
  AsyncWaiterTest() {}

 private:
  Environment environment_;
  RunLoop run_loop_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(AsyncWaiterTest);
};

// Verifies AsyncWaitCallback is notified when pipe is ready.
TEST_F(AsyncWaiterTest, CallbackNotified) {
  TestAsyncWaitCallback callback;
  MessagePipe test_pipe;
  EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string()));

  AsyncWaiter waiter(test_pipe.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE,
                     ManualCallback(&callback));
  RunLoop::current()->Run();
  EXPECT_EQ(1, callback.result_count());
  EXPECT_EQ(MOJO_RESULT_OK, callback.last_result());
}

// Verifies 2 AsyncWaitCallbacks are notified when there pipes are ready.
TEST_F(AsyncWaiterTest, TwoCallbacksNotified) {
  TestAsyncWaitCallback callback1;
  TestAsyncWaitCallback callback2;
  MessagePipe test_pipe1;
  MessagePipe test_pipe2;
  EXPECT_TRUE(test::WriteTextMessage(test_pipe1.handle1.get(), std::string()));
  EXPECT_TRUE(test::WriteTextMessage(test_pipe2.handle1.get(), std::string()));

  AsyncWaiter waiter1(test_pipe1.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE,
                      ManualCallback(&callback1));
  AsyncWaiter waiter2(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE,
                      ManualCallback(&callback2));

  RunLoop::current()->Run();
  EXPECT_EQ(1, callback1.result_count());
  EXPECT_EQ(MOJO_RESULT_OK, callback1.last_result());
  EXPECT_EQ(1, callback2.result_count());
  EXPECT_EQ(MOJO_RESULT_OK, callback2.last_result());
}

// Verifies cancel works.
TEST_F(AsyncWaiterTest, CancelCallback) {
  TestAsyncWaitCallback callback;
  MessagePipe test_pipe;
  EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string()));

  {
    AsyncWaiter waiter(test_pipe.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE,
                       ManualCallback(&callback));
  }
  RunLoop::current()->Run();
  EXPECT_EQ(0, callback.result_count());
}

}  // namespace
}  // namespace mojo