Home | History | Annotate | Download | only in shill
      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:
     47   PPPDaemonTest() : weak_ptr_factory_(this) {}
     48   virtual ~PPPDaemonTest() {}
     49 
     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 
     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 
     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 
     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 
    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