blob: de5982f4e8477f226c75789b1209fdce34d94edd [file] [log] [blame]
Paul Stewart75897df2011-04-27 09:05:53 -07001// Copyright (c) 2011 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
Paul Stewart75897df2011-04-27 09:05:53 -07005#include <stdint.h>
6#include <glib.h>
7
Chris Masone487b8bf2011-05-13 16:27:57 -07008#include <base/callback_old.h>
Chris Masoneee929b72011-05-10 10:02:18 -07009#include <base/logging.h>
Chris Masone487b8bf2011-05-13 16:27:57 -070010#include <base/memory/ref_counted.h>
Chris Masone0e1d1042011-05-09 18:07:03 -070011#include <base/message_loop_proxy.h>
12#include <base/stringprintf.h>
Chris Masoneee929b72011-05-10 10:02:18 -070013#include <gtest/gtest.h>
14#include <gmock/gmock.h>
15
Paul Stewart75897df2011-04-27 09:05:53 -070016#include "shill/shill_daemon.h"
Chris Masoned7732e42011-05-20 11:08:56 -070017#include "shill/mock_control.h"
Paul Stewart75897df2011-04-27 09:05:53 -070018
19namespace shill {
20using ::testing::Test;
21using ::testing::_;
Chris Masone0e1d1042011-05-09 18:07:03 -070022using ::testing::Gt;
Paul Stewart75897df2011-04-27 09:05:53 -070023using ::testing::NotNull;
24using ::testing::Return;
Paul Stewart75897df2011-04-27 09:05:53 -070025using ::testing::StrictMock;
26
27class MockEventDispatchTester {
28 public:
29 explicit MockEventDispatchTester(EventDispatcher *dispatcher)
Chris Masone0e1d1042011-05-09 18:07:03 -070030 : dispatcher_(dispatcher),
31 triggered_(false),
32 callback_count_(0),
33 got_data_(false),
34 data_callback_(NULL),
35 input_handler_(NULL),
36 tester_factory_(this) {
Paul Stewart75897df2011-04-27 09:05:53 -070037 }
38
Chris Masone0e1d1042011-05-09 18:07:03 -070039 void ScheduleTimedTasks() {
40 dispatcher_->PostDelayedTask(
41 tester_factory_.NewRunnableMethod(&MockEventDispatchTester::Trigger),
42 10);
43 // also set up a failsafe, so the test still exits even if something goes
44 // wrong. The Factory owns the RunnableMethod, but we get a pointer to it.
45 failsafe_ = tester_factory_.NewRunnableMethod(
46 &MockEventDispatchTester::QuitRegardless);
47 dispatcher_->PostDelayedTask(failsafe_, 100);
Paul Stewart75897df2011-04-27 09:05:53 -070048 }
49
Chris Masone0e1d1042011-05-09 18:07:03 -070050 void RescheduleUnlessTriggered() {
51 ++callback_count_;
Paul Stewart75897df2011-04-27 09:05:53 -070052 if (!triggered_) {
Chris Masone0e1d1042011-05-09 18:07:03 -070053 dispatcher_->PostTask(
54 tester_factory_.NewRunnableMethod(
55 &MockEventDispatchTester::RescheduleUnlessTriggered));
56 } else {
57 failsafe_->Cancel();
58 QuitRegardless();
Paul Stewart75897df2011-04-27 09:05:53 -070059 }
60 }
61
Chris Masone0e1d1042011-05-09 18:07:03 -070062 void QuitRegardless() {
63 dispatcher_->PostTask(new MessageLoop::QuitTask);
64 }
Paul Stewart75897df2011-04-27 09:05:53 -070065
Chris Masone0e1d1042011-05-09 18:07:03 -070066 void Trigger() {
67 LOG(INFO) << "MockEventDispatchTester handling " << callback_count_;
68 CallbackComplete(callback_count_);
69 triggered_ = true;
70 }
Paul Stewarta43d9232011-05-10 11:40:22 -070071
72 void HandleData(InputData *inputData) {
Chris Masone0e1d1042011-05-09 18:07:03 -070073 LOG(INFO) << "MockEventDispatchTester handling data len "
74 << base::StringPrintf("%d %.*s", inputData->len,
75 inputData->len, inputData->buf);
Paul Stewarta43d9232011-05-10 11:40:22 -070076 got_data_ = true;
77 IOComplete(inputData->len);
Chris Masone0e1d1042011-05-09 18:07:03 -070078 QuitRegardless();
Paul Stewarta43d9232011-05-10 11:40:22 -070079 }
Chris Masone0e1d1042011-05-09 18:07:03 -070080
Paul Stewarta43d9232011-05-10 11:40:22 -070081 bool GetData() { return got_data_; }
82
83 void ListenIO(int fd) {
Chris Masone0e1d1042011-05-09 18:07:03 -070084 data_callback_.reset(NewCallback(this,
85 &MockEventDispatchTester::HandleData));
86 input_handler_.reset(dispatcher_->CreateInputHandler(fd,
87 data_callback_.get()));
Paul Stewarta43d9232011-05-10 11:40:22 -070088 }
89
90 void StopListenIO() {
91 got_data_ = false;
Chris Masone0e1d1042011-05-09 18:07:03 -070092 input_handler_.reset(NULL);
Paul Stewarta43d9232011-05-10 11:40:22 -070093 }
94
Paul Stewart75897df2011-04-27 09:05:53 -070095 MOCK_METHOD1(CallbackComplete, void(int));
Paul Stewarta43d9232011-05-10 11:40:22 -070096 MOCK_METHOD1(IOComplete, void(int));
Paul Stewart75897df2011-04-27 09:05:53 -070097 private:
Paul Stewarta43d9232011-05-10 11:40:22 -070098 EventDispatcher *dispatcher_;
Paul Stewart75897df2011-04-27 09:05:53 -070099 bool triggered_;
Chris Masone0e1d1042011-05-09 18:07:03 -0700100 int callback_count_;
Paul Stewarta43d9232011-05-10 11:40:22 -0700101 bool got_data_;
Chris Masone0e1d1042011-05-09 18:07:03 -0700102 scoped_ptr<Callback1<InputData*>::Type> data_callback_;
103 scoped_ptr<IOInputHandler> input_handler_;
104 ScopedRunnableMethodFactory<MockEventDispatchTester> tester_factory_;
105 CancelableTask* failsafe_;
Paul Stewart75897df2011-04-27 09:05:53 -0700106};
107
108class ShillDaemonTest : public Test {
109 public:
110 ShillDaemonTest()
Chris Masoned7732e42011-05-20 11:08:56 -0700111 : daemon_(&config_, new MockControl()),
Paul Stewart75897df2011-04-27 09:05:53 -0700112 dispatcher_(&daemon_.dispatcher_),
Paul Stewart0af98bf2011-05-10 17:38:08 -0700113 dispatcher_test_(dispatcher_),
Paul Stewartb50f0b92011-05-16 16:31:42 -0700114 device_info_(daemon_.control_, dispatcher_, &daemon_.manager_),
Chris Masone0e1d1042011-05-09 18:07:03 -0700115 factory_(this) {
116 }
117 virtual ~ShillDaemonTest() {}
Paul Stewart75897df2011-04-27 09:05:53 -0700118 virtual void SetUp() {
119 // Tests initialization done by the daemon's constructor
Chris Masone0e1d1042011-05-09 18:07:03 -0700120 ASSERT_NE(reinterpret_cast<Config*>(NULL), daemon_.config_);
121 ASSERT_NE(reinterpret_cast<ControlInterface*>(NULL), daemon_.control_);
Paul Stewart75897df2011-04-27 09:05:53 -0700122 }
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700123 protected:
Paul Stewart75897df2011-04-27 09:05:53 -0700124 Config config_;
125 Daemon daemon_;
Paul Stewart0af98bf2011-05-10 17:38:08 -0700126 DeviceInfo device_info_;
Paul Stewart75897df2011-04-27 09:05:53 -0700127 EventDispatcher *dispatcher_;
128 StrictMock<MockEventDispatchTester> dispatcher_test_;
Chris Masone0e1d1042011-05-09 18:07:03 -0700129 ScopedRunnableMethodFactory<ShillDaemonTest> factory_;
Paul Stewart75897df2011-04-27 09:05:53 -0700130};
131
132
133TEST_F(ShillDaemonTest, EventDispatcher) {
Chris Masone0e1d1042011-05-09 18:07:03 -0700134 EXPECT_CALL(dispatcher_test_, CallbackComplete(Gt(0)));
135 dispatcher_test_.ScheduleTimedTasks();
136 dispatcher_test_.RescheduleUnlessTriggered();
137 dispatcher_->DispatchForever();
Paul Stewarta43d9232011-05-10 11:40:22 -0700138
139 EXPECT_CALL(dispatcher_test_, IOComplete(16));
140 int pipefd[2];
Chris Masone0e1d1042011-05-09 18:07:03 -0700141 ASSERT_EQ(pipe(pipefd), 0);
Paul Stewarta43d9232011-05-10 11:40:22 -0700142
143 dispatcher_test_.ListenIO(pipefd[0]);
Chris Masone0e1d1042011-05-09 18:07:03 -0700144 ASSERT_EQ(write(pipefd[1], "This is a test?!", 16), 16);
Paul Stewarta43d9232011-05-10 11:40:22 -0700145
Chris Masone0e1d1042011-05-09 18:07:03 -0700146 dispatcher_->DispatchForever();
Paul Stewarta43d9232011-05-10 11:40:22 -0700147 dispatcher_test_.StopListenIO();
Chris Masone0e1d1042011-05-09 18:07:03 -0700148}
149
Chris Masone9be4a9d2011-05-16 15:44:09 -0700150} // namespace shill