blob: 9de15dae491cb8857a0d3a6bd0d3bb96d504325d [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewart75897df2011-04-27 09:05:53 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Paul Stewart75897df2011-04-27 09:05:53 -07005#include <stdint.h>
Paul Stewart75897df2011-04-27 09:05:53 -07006
Ben Chancd477322014-10-17 14:19:30 -07007#include <memory>
8
Eric Shienbrood3e20a232012-02-16 11:35:56 -05009#include <base/bind.h>
10#include <base/cancelable_callback.h>
Chris Masone487b8bf2011-05-13 16:27:57 -070011#include <base/memory/ref_counted.h>
Ben Chana0ddf462014-02-06 11:32:42 -080012#include <base/message_loop/message_loop_proxy.h>
13#include <base/strings/stringprintf.h>
Chris Masoneee929b72011-05-10 10:02:18 -070014#include <gmock/gmock.h>
Darin Petkov887f2982011-07-14 16:10:17 -070015#include <gtest/gtest.h>
Chris Masoneee929b72011-05-10 10:02:18 -070016
Christopher Wileyb691efd2012-08-09 13:51:51 -070017#include "shill/logging.h"
Darin Petkov887f2982011-07-14 16:10:17 -070018#include "shill/mock_control.h"
Thieu Lefb46caf2012-03-08 11:57:15 -080019#include "shill/mock_dhcp_provider.h"
20#include "shill/mock_manager.h"
Thieu Le6c1e3bb2013-02-06 15:20:35 -080021#include "shill/mock_metrics.h"
Thieu Lefb46caf2012-03-08 11:57:15 -080022#include "shill/mock_proxy_factory.h"
Thieu Lefb46caf2012-03-08 11:57:15 -080023#include "shill/mock_routing_table.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070024#include "shill/net/io_handler.h"
Peter Qiu02e3dc32014-10-31 10:15:00 -070025#include "shill/net/mock_netlink_manager.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070026#include "shill/net/mock_rtnl_handler.h"
Peter Qiu02e3dc32014-10-31 10:15:00 -070027#include "shill/net/nl80211_message.h"
Paul Stewart75897df2011-04-27 09:05:53 -070028#include "shill/shill_daemon.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070029#include "shill/shill_test_config.h"
Paul Stewart75897df2011-04-27 09:05:53 -070030
Eric Shienbrood3e20a232012-02-16 11:35:56 -050031using base::Bind;
32using base::Callback;
33using base::CancelableClosure;
Gary Moraina9fb3252012-05-31 12:05:31 -070034using base::Unretained;
Eric Shienbrood3e20a232012-02-16 11:35:56 -050035using base::WeakPtrFactory;
36
Thieu Lefb46caf2012-03-08 11:57:15 -080037using ::testing::Expectation;
Chris Masone0e1d1042011-05-09 18:07:03 -070038using ::testing::Gt;
Thieu Le6c1e3bb2013-02-06 15:20:35 -080039using ::testing::Mock;
Paul Stewart75897df2011-04-27 09:05:53 -070040using ::testing::NotNull;
41using ::testing::Return;
Paul Stewart75897df2011-04-27 09:05:53 -070042using ::testing::StrictMock;
Thieu Lefb46caf2012-03-08 11:57:15 -080043using ::testing::Test;
44using ::testing::_;
45
46namespace shill {
Paul Stewart75897df2011-04-27 09:05:53 -070047
48class MockEventDispatchTester {
49 public:
50 explicit MockEventDispatchTester(EventDispatcher *dispatcher)
Chris Masone0e1d1042011-05-09 18:07:03 -070051 : dispatcher_(dispatcher),
52 triggered_(false),
53 callback_count_(0),
54 got_data_(false),
Paul Stewartf0aae102011-10-19 12:11:44 -070055 got_ready_(false),
Chris Masone0e1d1042011-05-09 18:07:03 -070056 tester_factory_(this) {
Paul Stewart75897df2011-04-27 09:05:53 -070057 }
58
Paul Stewartf0aae102011-10-19 12:11:44 -070059 void ScheduleFailSafe() {
60 // Set up a failsafe, so the test still exits even if something goes
Eric Shienbrood3e20a232012-02-16 11:35:56 -050061 // wrong.
62 failsafe_.Reset(Bind(&MockEventDispatchTester::StopDispatcher,
63 tester_factory_.GetWeakPtr()));
64 dispatcher_->PostDelayedTask(failsafe_.callback(), 100);
Paul Stewartf0aae102011-10-19 12:11:44 -070065 }
66
Chris Masone0e1d1042011-05-09 18:07:03 -070067 void ScheduleTimedTasks() {
68 dispatcher_->PostDelayedTask(
Eric Shienbrood3e20a232012-02-16 11:35:56 -050069 Bind(&MockEventDispatchTester::Trigger, tester_factory_.GetWeakPtr()),
Chris Masone0e1d1042011-05-09 18:07:03 -070070 10);
Paul Stewart75897df2011-04-27 09:05:53 -070071 }
72
Chris Masone0e1d1042011-05-09 18:07:03 -070073 void RescheduleUnlessTriggered() {
74 ++callback_count_;
Paul Stewart75897df2011-04-27 09:05:53 -070075 if (!triggered_) {
Chris Masone0e1d1042011-05-09 18:07:03 -070076 dispatcher_->PostTask(
Eric Shienbrood3e20a232012-02-16 11:35:56 -050077 Bind(&MockEventDispatchTester::RescheduleUnlessTriggered,
78 tester_factory_.GetWeakPtr()));
Chris Masone0e1d1042011-05-09 18:07:03 -070079 } else {
Eric Shienbrood3e20a232012-02-16 11:35:56 -050080 failsafe_.Cancel();
Paul Stewartf0aae102011-10-19 12:11:44 -070081 StopDispatcher();
Paul Stewart75897df2011-04-27 09:05:53 -070082 }
83 }
84
Paul Stewartf0aae102011-10-19 12:11:44 -070085 void StopDispatcher() {
Ben Chana0ddf462014-02-06 11:32:42 -080086 dispatcher_->PostTask(base::MessageLoop::QuitClosure());
Chris Masone0e1d1042011-05-09 18:07:03 -070087 }
Paul Stewart75897df2011-04-27 09:05:53 -070088
Chris Masone0e1d1042011-05-09 18:07:03 -070089 void Trigger() {
90 LOG(INFO) << "MockEventDispatchTester handling " << callback_count_;
91 CallbackComplete(callback_count_);
92 triggered_ = true;
93 }
Paul Stewarta43d9232011-05-10 11:40:22 -070094
95 void HandleData(InputData *inputData) {
Chris Masone0e1d1042011-05-09 18:07:03 -070096 LOG(INFO) << "MockEventDispatchTester handling data len "
Paul Stewart83224402011-11-30 14:52:30 -080097 << base::StringPrintf("%zd %.*s", inputData->len,
98 static_cast<int>(inputData->len),
99 inputData->buf);
Paul Stewarta43d9232011-05-10 11:40:22 -0700100 got_data_ = true;
101 IOComplete(inputData->len);
Paul Stewartf0aae102011-10-19 12:11:44 -0700102 StopDispatcher();
Paul Stewarta43d9232011-05-10 11:40:22 -0700103 }
Chris Masone0e1d1042011-05-09 18:07:03 -0700104
Paul Stewarta43d9232011-05-10 11:40:22 -0700105 bool GetData() { return got_data_; }
106
107 void ListenIO(int fd) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500108 data_callback_ = Bind(&MockEventDispatchTester::HandleData,
109 tester_factory_.GetWeakPtr());
Paul Stewart5f06a0e2012-12-20 11:11:33 -0800110 input_handler_.reset(dispatcher_->CreateInputHandler(
111 fd, data_callback_, IOHandler::ErrorCallback()));
Paul Stewarta43d9232011-05-10 11:40:22 -0700112 }
113
114 void StopListenIO() {
115 got_data_ = false;
Paul Stewartca324742014-08-29 14:41:59 -0700116 input_handler_.reset(nullptr);
Paul Stewarta43d9232011-05-10 11:40:22 -0700117 }
118
Paul Stewartf0aae102011-10-19 12:11:44 -0700119 void HandleReady(int fd) {
120 // Stop event handling after we receive in input-ready event. We should
121 // no longer be called until events are re-enabled.
122 input_handler_->Stop();
123
124 if (got_ready_) {
125 // If we're still getting events after we have stopped them, something
126 // is really wrong, and we cannot just depend on ASSERT_FALSE() to get
127 // us out of it. Make sure the dispatcher is also stopped, or else we
128 // could end up never exiting.
129 StopDispatcher();
130 ASSERT_FALSE(got_ready_) << "failed to stop Input Ready events";
131 }
132 got_ready_ = true;
133
134 LOG(INFO) << "MockEventDispatchTester handling ready for fd " << fd;
135 IOComplete(callback_count_);
136
137 if (callback_count_) {
138 StopDispatcher();
139 } else {
140 // Restart Ready events after 10 millisecond delay.
141 callback_count_++;
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500142 dispatcher_->PostDelayedTask(
143 Bind(&MockEventDispatchTester::RestartReady,
144 tester_factory_.GetWeakPtr()),
145 10);
Paul Stewartf0aae102011-10-19 12:11:44 -0700146 }
147 }
148
149 void RestartReady() {
150 got_ready_ = false;
151 input_handler_->Start();
152 }
153
154 void ListenReady(int fd) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500155 ready_callback_ = Bind(&MockEventDispatchTester::HandleReady,
156 tester_factory_.GetWeakPtr());
Paul Stewartf0aae102011-10-19 12:11:44 -0700157 input_handler_.reset(
158 dispatcher_->CreateReadyHandler(fd, IOHandler::kModeInput,
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500159 ready_callback_));
Paul Stewartf0aae102011-10-19 12:11:44 -0700160 }
161
162 void StopListenReady() {
163 got_ready_ = false;
Paul Stewartca324742014-08-29 14:41:59 -0700164 input_handler_.reset(nullptr);
Paul Stewartf0aae102011-10-19 12:11:44 -0700165 }
166
Paul Stewart56615602014-07-17 19:28:12 -0700167 MOCK_METHOD1(CallbackComplete, void(int callback_count));
168 MOCK_METHOD1(IOComplete, void(int data_length));
Paul Stewart26b327e2011-10-19 11:38:09 -0700169
Paul Stewart75897df2011-04-27 09:05:53 -0700170 private:
Paul Stewarta43d9232011-05-10 11:40:22 -0700171 EventDispatcher *dispatcher_;
Paul Stewart75897df2011-04-27 09:05:53 -0700172 bool triggered_;
Chris Masone0e1d1042011-05-09 18:07:03 -0700173 int callback_count_;
Paul Stewarta43d9232011-05-10 11:40:22 -0700174 bool got_data_;
Paul Stewartf0aae102011-10-19 12:11:44 -0700175 bool got_ready_;
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500176 Callback<void(InputData*)> data_callback_;
177 Callback<void(int)> ready_callback_;
Ben Chancd477322014-10-17 14:19:30 -0700178 std::unique_ptr<IOHandler> input_handler_;
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500179 WeakPtrFactory<MockEventDispatchTester> tester_factory_;
180 CancelableClosure failsafe_;
Paul Stewart75897df2011-04-27 09:05:53 -0700181};
182
183class ShillDaemonTest : public Test {
184 public:
185 ShillDaemonTest()
Paul Stewartca324742014-08-29 14:41:59 -0700186 : daemon_(&config_, new MockControl()), // Passes ownership.
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800187 metrics_(new MockMetrics(&daemon_.dispatcher_)),
Paul Stewartca324742014-08-29 14:41:59 -0700188 manager_(new MockManager(daemon_.control_.get(),
Thieu Lefb46caf2012-03-08 11:57:15 -0800189 &daemon_.dispatcher_,
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800190 metrics_,
Thieu Lefb46caf2012-03-08 11:57:15 -0800191 &daemon_.glib_)),
Yunlian Jiangae1b5362013-12-03 10:54:09 -0800192 dispatcher_(&daemon_.dispatcher_),
Paul Stewartca324742014-08-29 14:41:59 -0700193 device_info_(daemon_.control_.get(), dispatcher_, metrics_,
Thieu Lefb46caf2012-03-08 11:57:15 -0800194 daemon_.manager_.get()),
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500195 dispatcher_test_(dispatcher_) {
Chris Masone0e1d1042011-05-09 18:07:03 -0700196 }
197 virtual ~ShillDaemonTest() {}
Paul Stewart75897df2011-04-27 09:05:53 -0700198 virtual void SetUp() {
199 // Tests initialization done by the daemon's constructor
Paul Stewartca324742014-08-29 14:41:59 -0700200 ASSERT_NE(nullptr, daemon_.config_);
201 ASSERT_NE(nullptr, daemon_.control_.get());
Thieu Lefb46caf2012-03-08 11:57:15 -0800202 daemon_.proxy_factory_ = &proxy_factory_;
203 daemon_.rtnl_handler_ = &rtnl_handler_;
204 daemon_.routing_table_ = &routing_table_;
205 daemon_.dhcp_provider_ = &dhcp_provider_;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800206 daemon_.metrics_.reset(metrics_); // Passes ownership
Thieu Lefb46caf2012-03-08 11:57:15 -0800207 daemon_.manager_.reset(manager_); // Passes ownership
Wade Guthriefa2100e2013-05-15 10:11:22 -0700208 daemon_.netlink_manager_ = &netlink_manager_;
Paul Stewartf0aae102011-10-19 12:11:44 -0700209 dispatcher_test_.ScheduleFailSafe();
Wade Guthriefa2100e2013-05-15 10:11:22 -0700210
211 const uint16_t kNl80211MessageType = 42; // Arbitrary.
212 ON_CALL(netlink_manager_, GetFamily(Nl80211Message::kMessageTypeString, _)).
213 WillByDefault(Return(kNl80211MessageType));
Paul Stewart75897df2011-04-27 09:05:53 -0700214 }
Thieu Lefb46caf2012-03-08 11:57:15 -0800215 void StartDaemon() {
216 daemon_.Start();
217 }
218
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800219 void StopDaemon() {
220 daemon_.Stop();
221 }
222
Wade Guthriebb9fca22013-04-10 17:21:42 -0700223 void ResetNetlinkManager() {
224 daemon_.netlink_manager_->Reset(true);
Darin Petkovd5818382013-01-28 16:27:07 +0100225 }
226
Gary Moraina9fb3252012-05-31 12:05:31 -0700227 MOCK_METHOD0(TerminationAction, void());
228
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700229 protected:
Chris Masoneb9c00592011-10-06 13:10:39 -0700230 TestConfig config_;
Paul Stewart75897df2011-04-27 09:05:53 -0700231 Daemon daemon_;
Thieu Lefb46caf2012-03-08 11:57:15 -0800232 MockProxyFactory proxy_factory_;
233 MockRTNLHandler rtnl_handler_;
234 MockRoutingTable routing_table_;
235 MockDHCPProvider dhcp_provider_;
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800236 MockMetrics *metrics_;
Thieu Lefb46caf2012-03-08 11:57:15 -0800237 MockManager *manager_;
Wade Guthriefa2100e2013-05-15 10:11:22 -0700238 MockNetlinkManager netlink_manager_;
Paul Stewart75897df2011-04-27 09:05:53 -0700239 EventDispatcher *dispatcher_;
Yunlian Jiangae1b5362013-12-03 10:54:09 -0800240 DeviceInfo device_info_;
Paul Stewart75897df2011-04-27 09:05:53 -0700241 StrictMock<MockEventDispatchTester> dispatcher_test_;
242};
243
244
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800245TEST_F(ShillDaemonTest, StartStop) {
Thieu Lefb46caf2012-03-08 11:57:15 -0800246 // To ensure we do not have any stale routes, we flush a device's routes
247 // when it is started. This requires that the routing table is fully
248 // populated before we create and start devices. So test to make sure that
249 // the RoutingTable starts before the Manager (which in turn starts
250 // DeviceInfo who is responsible for creating and starting devices).
251 // The result is that we request the dump of the routing table and when that
252 // completes, we request the dump of the links. For each link found, we
253 // create and start the device.
254 EXPECT_CALL(proxy_factory_, Init());
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800255 EXPECT_CALL(*metrics_, Start());
Peter Qiu37a2b602014-10-27 10:00:43 -0700256 EXPECT_CALL(rtnl_handler_, Start(_));
Thieu Lefb46caf2012-03-08 11:57:15 -0800257 Expectation routing_table_started = EXPECT_CALL(routing_table_, Start());
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700258 EXPECT_CALL(dhcp_provider_, Init(_, _, _, _));
Thieu Lefb46caf2012-03-08 11:57:15 -0800259 EXPECT_CALL(*manager_, Start()).After(routing_table_started);
260 StartDaemon();
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800261 Mock::VerifyAndClearExpectations(metrics_);
262 Mock::VerifyAndClearExpectations(manager_);
263
264 EXPECT_CALL(*manager_, Stop());
265 EXPECT_CALL(*metrics_, Stop());
266 StopDaemon();
Thieu Lefb46caf2012-03-08 11:57:15 -0800267}
268
Paul Stewartf0aae102011-10-19 12:11:44 -0700269TEST_F(ShillDaemonTest, EventDispatcherTimer) {
Chris Masone0e1d1042011-05-09 18:07:03 -0700270 EXPECT_CALL(dispatcher_test_, CallbackComplete(Gt(0)));
271 dispatcher_test_.ScheduleTimedTasks();
272 dispatcher_test_.RescheduleUnlessTriggered();
273 dispatcher_->DispatchForever();
Paul Stewartf0aae102011-10-19 12:11:44 -0700274}
Paul Stewarta43d9232011-05-10 11:40:22 -0700275
Paul Stewartf0aae102011-10-19 12:11:44 -0700276TEST_F(ShillDaemonTest, EventDispatcherIO) {
Paul Stewarta43d9232011-05-10 11:40:22 -0700277 EXPECT_CALL(dispatcher_test_, IOComplete(16));
278 int pipefd[2];
Chris Masone0e1d1042011-05-09 18:07:03 -0700279 ASSERT_EQ(pipe(pipefd), 0);
Paul Stewarta43d9232011-05-10 11:40:22 -0700280
281 dispatcher_test_.ListenIO(pipefd[0]);
Chris Masone0e1d1042011-05-09 18:07:03 -0700282 ASSERT_EQ(write(pipefd[1], "This is a test?!", 16), 16);
Paul Stewarta43d9232011-05-10 11:40:22 -0700283
Chris Masone0e1d1042011-05-09 18:07:03 -0700284 dispatcher_->DispatchForever();
Paul Stewarta43d9232011-05-10 11:40:22 -0700285 dispatcher_test_.StopListenIO();
Chris Masone0e1d1042011-05-09 18:07:03 -0700286}
287
Paul Stewartf0aae102011-10-19 12:11:44 -0700288TEST_F(ShillDaemonTest, EventDispatcherReady) {
289 EXPECT_CALL(dispatcher_test_, IOComplete(0))
290 .Times(1);
291 EXPECT_CALL(dispatcher_test_, IOComplete(1))
292 .Times(1);
293
294 int pipefd[2];
295 ASSERT_EQ(pipe(pipefd), 0);
296
297 dispatcher_test_.ListenReady(pipefd[0]);
298 ASSERT_EQ(write(pipefd[1], "This is a test?!", 16), 16);
299
300 dispatcher_->DispatchForever();
301 dispatcher_test_.StopListenReady();
302}
303
Gary Moraina9fb3252012-05-31 12:05:31 -0700304ACTION_P2(CompleteAction, manager, name) {
305 manager->TerminationActionComplete(name);
306}
307
308TEST_F(ShillDaemonTest, Quit) {
309 // The following expectations are to satisfy calls in Daemon::Start().
310 EXPECT_CALL(proxy_factory_, Init());
Peter Qiu37a2b602014-10-27 10:00:43 -0700311 EXPECT_CALL(rtnl_handler_, Start(_));
Gary Moraina9fb3252012-05-31 12:05:31 -0700312 EXPECT_CALL(routing_table_, Start());
Paul Stewart3bdf1ab2014-07-17 19:22:26 -0700313 EXPECT_CALL(dhcp_provider_, Init(_, _, _, _));
Gary Moraina9fb3252012-05-31 12:05:31 -0700314 EXPECT_CALL(*manager_, Start());
315
316 // This expectation verifies that the termination actions are invoked.
317 EXPECT_CALL(*this, TerminationAction())
318 .WillOnce(CompleteAction(manager_, "daemon test"));
319
320 manager_->AddTerminationAction("daemon test",
321 Bind(&ShillDaemonTest::TerminationAction,
322 Unretained(this)));
323
324 // Run Daemon::Quit() after the daemon starts running.
325 dispatcher_->PostTask(Bind(&Daemon::Quit, Unretained(&daemon_)));
Wade Guthriebee87c22013-03-06 11:00:46 -0800326
Gary Moraina9fb3252012-05-31 12:05:31 -0700327 daemon_.Run();
Wade Guthriebb9fca22013-04-10 17:21:42 -0700328 ResetNetlinkManager();
Gary Moraina9fb3252012-05-31 12:05:31 -0700329}
330
Chris Masone9be4a9d2011-05-16 15:44:09 -0700331} // namespace shill