1 //
2 // Copyright (C) 2014 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 "apmanager/dhcp_server.h"
18
19 #include <string>
20
21 #include <net/if.h>
22
23 #include <base/strings/string_util.h>
24 #include <base/strings/stringprintf.h>
25 #include <brillo/process_mock.h>
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
28 #include <shill/net/mock_rtnl_handler.h>
29
30 #include "apmanager/mock_file_writer.h"
31 #include "apmanager/mock_process_factory.h"
32
33 using brillo::ProcessMock;
34 using ::testing::_;
35 using ::testing::Mock;
36 using ::testing::Return;
37 using std::string;
38
39 namespace {
40 const uint16_t kServerAddressIndex = 1;
41 const char kTestInterfaceName[] = "test_interface";
42 const char kExpectedDnsmasqConfigFile[] =
43 "port=0\n"
44 "bind-interfaces\n"
45 "log-dhcp\n"
46 "keep-in-foreground\n"
47 "dhcp-range=192.168.1.1,192.168.1.128\n"
48 "interface=test_interface\n"
49 #if !defined(__ANDROID__)
50 "user=apmanager\n"
51 "dhcp-leasefile=/var/run/apmanager/dnsmasq/dhcpd-1.leases\n";
52 #else
53 "user=system\n"
54 "dhcp-leasefile=/data/misc/apmanager/dnsmasq/dhcpd-1.leases\n";
55 #endif // __ANDROID__
56
57 #if !defined(__ANDROID__)
58 const char kBinSleep[] = "/bin/sleep";
59 const char kDnsmasqConfigFilePath[] =
60 "/var/run/apmanager/dnsmasq/dhcpd-1.conf";
61 #else
62 const char kBinSleep[] = "/system/bin/sleep";
63 const char kDnsmasqConfigFilePath[] =
64 "/data/misc/apmanager/dnsmasq/dhcpd-1.conf";
65 #endif // __ANDROID__
66 } // namespace
67
68 namespace apmanager {
69
70 class DHCPServerTest : public testing::Test {
71 public:
DHCPServerTest()72 DHCPServerTest()
73 : dhcp_server_(new DHCPServer(kServerAddressIndex, kTestInterfaceName)),
74 rtnl_handler_(new shill::MockRTNLHandler()) {}
~DHCPServerTest()75 virtual ~DHCPServerTest() {}
76
SetUp()77 virtual void SetUp() {
78 dhcp_server_->rtnl_handler_ = rtnl_handler_.get();
79 dhcp_server_->file_writer_ = &file_writer_;
80 dhcp_server_->process_factory_ = &process_factory_;
81 }
82
TearDown()83 virtual void TearDown() {
84 // Reset DHCP server now while RTNLHandler is still valid.
85 dhcp_server_.reset();
86 }
87
StartDummyProcess()88 void StartDummyProcess() {
89 dhcp_server_->dnsmasq_process_.reset(new brillo::ProcessImpl);
90 dhcp_server_->dnsmasq_process_->AddArg(kBinSleep);
91 dhcp_server_->dnsmasq_process_->AddArg("12345");
92 CHECK(dhcp_server_->dnsmasq_process_->Start());
93 }
94
GenerateConfigFile()95 string GenerateConfigFile() {
96 return dhcp_server_->GenerateConfigFile();
97 }
98
99 protected:
100 std::unique_ptr<DHCPServer> dhcp_server_;
101 std::unique_ptr<shill::MockRTNLHandler> rtnl_handler_;
102 MockFileWriter file_writer_;
103 MockProcessFactory process_factory_;
104 };
105
106
TEST_F(DHCPServerTest,GenerateConfigFile)107 TEST_F(DHCPServerTest, GenerateConfigFile) {
108 string config_content = GenerateConfigFile();
109 EXPECT_STREQ(kExpectedDnsmasqConfigFile, config_content.c_str())
110 << "Expected to find the following config...\n"
111 << kExpectedDnsmasqConfigFile << ".....\n"
112 << config_content;
113 }
114
TEST_F(DHCPServerTest,StartWhenServerAlreadyStarted)115 TEST_F(DHCPServerTest, StartWhenServerAlreadyStarted) {
116 StartDummyProcess();
117
118 EXPECT_FALSE(dhcp_server_->Start());
119 }
120
TEST_F(DHCPServerTest,StartSuccess)121 TEST_F(DHCPServerTest, StartSuccess) {
122 ProcessMock* process = new ProcessMock();
123
124 const int kInterfaceIndex = 1;
125 EXPECT_CALL(file_writer_,
126 Write(kDnsmasqConfigFilePath, kExpectedDnsmasqConfigFile))
127 .WillOnce(Return(true));
128 EXPECT_CALL(*rtnl_handler_.get(), GetInterfaceIndex(kTestInterfaceName))
129 .WillOnce(Return(kInterfaceIndex));
130 EXPECT_CALL(*rtnl_handler_.get(),
131 AddInterfaceAddress(kInterfaceIndex, _, _, _)).Times(1);
132 EXPECT_CALL(*rtnl_handler_.get(),
133 SetInterfaceFlags(kInterfaceIndex, IFF_UP, IFF_UP)).Times(1);
134 EXPECT_CALL(process_factory_, CreateProcess()).WillOnce(Return(process));
135 EXPECT_CALL(*process, Start()).WillOnce(Return(true));
136 EXPECT_TRUE(dhcp_server_->Start());
137 Mock::VerifyAndClearExpectations(rtnl_handler_.get());
138 }
139
140 } // namespace apmanager
141