blob: bb3ff14eb13799beb707335044f4fa66ba63d037 [file] [log] [blame]
Gary Morainf80ef062012-05-16 14:57:04 -07001// Copyright (c) 2012 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 "shill/hook_table.h"
6
7#include <base/bind.h>
8#include <base/callback.h>
9#include <gmock/gmock.h>
10#include <gtest/gtest.h>
11
12#include "shill/error.h"
13#include "shill/mock_event_dispatcher.h"
14
15using base::Callback;
16using base::Closure;
17using base::Bind;
18using base::Unretained;
19using ::testing::_;
20using ::testing::InSequence;
21using ::testing::Return;
22using ::testing::SaveArg;
23
24namespace shill {
25
26class HookTableTest : public testing::Test {
27 public:
28 MOCK_METHOD0(StartAction, void());
29 MOCK_METHOD0(PollAction, bool());
30 MOCK_METHOD1(DoneAction, void(const Error &));
31
32 protected:
33 HookTableTest()
34 : hook_table_(&event_dispatcher_) {}
35
36 MockEventDispatcher event_dispatcher_;
37 HookTable hook_table_;
38};
39
40MATCHER(IsSuccess, "") {
41 return arg.IsSuccess();
42}
43
44MATCHER(IsFailure, "") {
45 return arg.IsFailure();
46}
47
48TEST_F(HookTableTest, ActionCompletesImmediately) {
49 EXPECT_CALL(*this, StartAction());
50 EXPECT_CALL(*this, PollAction()).WillOnce(Return(true));
51 EXPECT_CALL(*this, DoneAction(IsSuccess()));
52 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(0);
53 Closure start_cb = Bind(&HookTableTest::StartAction, Unretained(this));
54 Callback<bool()> poll_cb = Bind(&HookTableTest::PollAction, Unretained(this));
55 Callback<void(const Error &)> done_cb = Bind(&HookTableTest::DoneAction,
56 Unretained(this));
57 hook_table_.Add("test", start_cb, poll_cb);
58 hook_table_.Run(0, done_cb);
59}
60
61TEST_F(HookTableTest, DelayedAction) {
62 Closure pending_cb;
63 const int kTimeout = 10;
64 const int64 kExpectedDelay = kTimeout * 1000 / HookTable::kPollIterations;
65 EXPECT_CALL(*this, StartAction());
66 {
67 InSequence s;
68 EXPECT_CALL(*this, PollAction()).WillOnce(Return(false));
69 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, kExpectedDelay))
70 .WillOnce(SaveArg<0>(&pending_cb));
71 EXPECT_CALL(*this, PollAction()).WillOnce(Return(true));
72 EXPECT_CALL(*this, DoneAction(IsSuccess()));
73 }
74 Closure start_cb = Bind(&HookTableTest::StartAction, Unretained(this));
75 Callback<bool()> poll_cb = Bind(&HookTableTest::PollAction, Unretained(this));
76 Callback<void(const Error &)> done_cb = Bind(&HookTableTest::DoneAction,
77 Unretained(this));
78
79 hook_table_.Add("test", start_cb, poll_cb);
80 hook_table_.Run(kTimeout, done_cb);
81 ASSERT_FALSE(pending_cb.is_null());
82 pending_cb.Run();
83}
84
85TEST_F(HookTableTest, ActionTimesOut) {
86 Closure pending_cb;
87 const int kTimeout = 10;
88 const int64 kExpectedDelay = kTimeout * 1000 / HookTable::kPollIterations;
89 EXPECT_CALL(*this, StartAction());
90 EXPECT_CALL(*this, PollAction()).WillRepeatedly(Return(false));
91 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, kExpectedDelay))
92 .Times(HookTable::kPollIterations)
93 .WillRepeatedly(SaveArg<0>(&pending_cb));
94 EXPECT_CALL(*this, DoneAction(IsFailure()));
95
96 Closure start_cb = Bind(&HookTableTest::StartAction, Unretained(this));
97 Callback<bool()> poll_cb = Bind(&HookTableTest::PollAction, Unretained(this));
98 Callback<void(const Error &)> done_cb = Bind(&HookTableTest::DoneAction,
99 Unretained(this));
100
101 hook_table_.Add("test", start_cb, poll_cb);
102 hook_table_.Run(kTimeout, done_cb);
103 for (int i = 0; i < HookTable::kPollIterations; ++i) {
104 ASSERT_FALSE(pending_cb.is_null());
105 pending_cb.Run();
106 }
107}
108
109TEST_F(HookTableTest, MultipleActionsAllSucceed) {
110 Closure pending_cb;
111 const int kTimeout = 10;
112 EXPECT_CALL(*this, StartAction()).Times(3);
113 EXPECT_CALL(*this, PollAction())
114 .Times(3)
115 .WillRepeatedly(Return(true));
116 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, _)).Times(0);
117 EXPECT_CALL(*this, DoneAction(IsSuccess()));
118
119 Closure start_cb = Bind(&HookTableTest::StartAction, Unretained(this));
120 Callback<bool()> poll_cb = Bind(&HookTableTest::PollAction, Unretained(this));
121 Callback<void(const Error &)> done_cb = Bind(&HookTableTest::DoneAction,
122 Unretained(this));
123
124 hook_table_.Add("test1", start_cb, poll_cb);
125 hook_table_.Add("test2", start_cb, poll_cb);
126 hook_table_.Add("test3", start_cb, poll_cb);
127 hook_table_.Run(kTimeout, done_cb);
128}
129
130TEST_F(HookTableTest, MultipleActionsAndOneTimesOut) {
131 Closure pending_cb;
132 const int kTimeout = 10;
133 const int64 kExpectedDelay = kTimeout * 1000 / HookTable::kPollIterations;
134 EXPECT_CALL(*this, StartAction()).Times(3);
135 EXPECT_CALL(*this, PollAction())
136 .Times((HookTable::kPollIterations + 1) * 3)
137 .WillOnce(Return(true))
138 .WillOnce(Return(true))
139 .WillRepeatedly(Return(false));
140 EXPECT_CALL(event_dispatcher_, PostDelayedTask(_, kExpectedDelay))
141 .Times(HookTable::kPollIterations)
142 .WillRepeatedly(SaveArg<0>(&pending_cb));
143 EXPECT_CALL(*this, DoneAction(IsFailure()));
144
145 Closure start_cb = Bind(&HookTableTest::StartAction, Unretained(this));
146 Callback<bool()> poll_cb = Bind(&HookTableTest::PollAction, Unretained(this));
147 Callback<void(const Error &)> done_cb = Bind(&HookTableTest::DoneAction,
148 Unretained(this));
149
150 hook_table_.Add("test1", start_cb, poll_cb);
151 hook_table_.Add("test2", start_cb, poll_cb);
152 hook_table_.Add("test3", start_cb, poll_cb);
153 hook_table_.Run(kTimeout, done_cb);
154 for (int i = 0; i < HookTable::kPollIterations; ++i) {
155 ASSERT_FALSE(pending_cb.is_null());
156 pending_cb.Run();
157 }
158}
159
160} // namespace shill