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