1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <map>
18 #include <memory>
19 #include <set>
20 #include <string>
21 #include <vector>
22
23 #include <base/bind.h>
24 #include <base/bind_helpers.h>
25 #include <base/memory/weak_ptr.h>
26 #include <gtest/gtest.h>
27
28 #include "shill/error.h"
29 #include "shill/external_task.h"
30 #include "shill/mock_control.h"
31 #include "shill/mock_process_manager.h"
32 #include "shill/ppp_daemon.h"
33 #include "shill/rpc_task.h"
34
35 namespace shill {
36
37 using std::string;
38 using std::vector;
39 using testing::_;
40 using testing::Invoke;
41 using testing::Return;
42 using testing::Test;
43 using testing::WithArg;
44
45 class PPPDaemonTest : public Test, public RPCTaskDelegate {
46 public:
PPPDaemonTest()47 PPPDaemonTest() : weak_ptr_factory_(this) {}
~PPPDaemonTest()48 virtual ~PPPDaemonTest() {}
49
Start(const PPPDaemon::Options & options,const std::string & device,Error * error)50 std::unique_ptr<ExternalTask> Start(const PPPDaemon::Options& options,
51 const std::string& device,
52 Error* error) {
53 PPPDaemon::DeathCallback callback(base::Bind(&PPPDaemonTest::DeathCallback,
54 base::Unretained(this)));
55 return PPPDaemon::Start(&control_, &process_manager_,
56 weak_ptr_factory_.GetWeakPtr(),
57 options, device, callback, error);
58 }
59
CaptureArgv(const vector<string> & argv)60 bool CaptureArgv(const vector<string>& argv) {
61 argv_ = argv;
62 return true;
63 }
64
65 MOCK_METHOD2(GetLogin, void(std::string* user, std::string* password));
66 MOCK_METHOD2(Notify, void(const std::string& reason,
67 const std::map<std::string, std::string>& dict));
68
69 protected:
70 MockControl control_;
71 MockProcessManager process_manager_;
72
73 std::vector<std::string> argv_;
74 base::WeakPtrFactory<PPPDaemonTest> weak_ptr_factory_;
75
76 MOCK_METHOD2(DeathCallback, void(pid_t pid, int status));
77
78 private:
79 DISALLOW_COPY_AND_ASSIGN(PPPDaemonTest);
80 };
81
TEST_F(PPPDaemonTest,PluginUsed)82 TEST_F(PPPDaemonTest, PluginUsed) {
83 EXPECT_CALL(process_manager_, StartProcess(_, _, _, _, _, _))
84 .WillOnce(WithArg<2>(Invoke(this, &PPPDaemonTest::CaptureArgv)));
85
86 Error error;
87 PPPDaemon::Options options;
88 std::unique_ptr<ExternalTask> task(Start(options, "eth0", &error));
89
90 for (size_t i = 0; i < argv_.size(); ++i) {
91 if (argv_[i] == "plugin") {
92 EXPECT_EQ(argv_[i + 1], PPPDaemon::kShimPluginPath);
93 }
94 }
95 }
96
TEST_F(PPPDaemonTest,OptionsConverted)97 TEST_F(PPPDaemonTest, OptionsConverted) {
98 EXPECT_CALL(process_manager_, StartProcess(_, _, _, _, _, _))
99 .WillOnce(WithArg<2>(Invoke(this, &PPPDaemonTest::CaptureArgv)));
100
101 PPPDaemon::Options options;
102 options.no_detach = true;
103 options.no_default_route = true;
104 options.use_peer_dns = true;
105 options.lcp_echo_interval = 1;
106 options.lcp_echo_failure = 1;
107 options.max_fail = 1;
108 options.use_ipv6 = true;
109
110 Error error;
111 std::unique_ptr<ExternalTask> task(Start(options, "eth0", &error));
112
113 std::set<std::string> expected_arguments = {
114 "nodetach", "nodefaultroute", "usepeerdns", "lcp-echo-interval",
115 "lcp-echo-failure", "maxfail", "+ipv6", "ipv6cp-use-ipaddr",
116 };
117 for (const auto& argument : argv_) {
118 expected_arguments.erase(argument);
119 }
120 EXPECT_TRUE(expected_arguments.empty());
121 }
122
TEST_F(PPPDaemonTest,ErrorPropagated)123 TEST_F(PPPDaemonTest, ErrorPropagated) {
124 EXPECT_CALL(process_manager_, StartProcess(_, _, _, _, _, _))
125 .WillOnce(Return(-1));
126
127 PPPDaemon::Options options;
128 Error error;
129 std::unique_ptr<ExternalTask> task(Start(options, "eth0", &error));
130
131 EXPECT_NE(error.type(), Error::kSuccess);
132 EXPECT_EQ(task.get(), nullptr);
133 }
134
135 } // namespace shill
136