1 /*
2 * Copyright (C) 2016, 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 <array>
18 #include <memory>
19
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <wifi_system_test/mock_interface_tool.h>
23
24 #include "android/net/wifi/IApInterface.h"
25 #include "wificond/tests/mock_netlink_manager.h"
26 #include "wificond/tests/mock_netlink_utils.h"
27 #include "wificond/tests/mock_scan_utils.h"
28 #include "wificond/server.h"
29
30 using android::net::wifi::IApInterface;
31 using android::net::wifi::IClientInterface;
32 using android::wifi_system::InterfaceTool;
33 using android::wifi_system::MockInterfaceTool;
34 using std::unique_ptr;
35 using std::vector;
36 using testing::Eq;
37 using testing::Invoke;
38 using testing::NiceMock;
39 using testing::Return;
40 using testing::Sequence;
41 using testing::StrEq;
42 using testing::_;
43
44 using namespace std::placeholders;
45
46 namespace android {
47 namespace wificond {
48 namespace {
49
50 const char kFakeInterfaceName[] = "testif0";
51 const char kFakeInterfaceName1[] = "testif1";
52 const char kFakeInterfaceNameP2p[] = "testif-p2p0";
53 const char kFateInterfaceNameInvalid[] = "testif-invalid";
54 const uint32_t kFakeInterfaceIndex = 34;
55 const uint32_t kFakeInterfaceIndex1 = 36;
56 const uint32_t kFakeInterfaceIndexP2p = 36;
57 const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
58 const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
59 const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddressP2p = {0x15, 0x24, 0xef, 0x27, 0x12, 0xff};
60
61 // This is a helper function to mock the behavior of
62 // NetlinkUtils::GetInterfaces().
63 // |wiphy_index| is mapped to first parameters of GetInterfaces().
64 // |response| is mapped to second parameters of GetInterfaces().
65 // |mock_response| and |mock_return_value| are additional parameters used
66 // for specifying expected results,
MockGetInterfacesResponse(const vector<InterfaceInfo> & mock_response,bool mock_return_value,uint32_t wiphy_index,vector<InterfaceInfo> * response)67 bool MockGetInterfacesResponse(
68 const vector<InterfaceInfo>& mock_response,
69 bool mock_return_value,
70 uint32_t wiphy_index,
71 vector<InterfaceInfo>* response) {
72 for (const auto& interface : mock_response) {
73 response->emplace_back(interface);
74 }
75 return mock_return_value;
76 }
77
78 class ServerTest : public ::testing::Test {
79 protected:
SetUp()80 void SetUp() override {
81 ON_CALL(*if_tool_, SetUpState(_, _)).WillByDefault(Return(true));
82 ON_CALL(*netlink_utils_, GetWiphyIndex(_)).WillByDefault(Return(true));
83 ON_CALL(*netlink_utils_, GetWiphyIndex(_, _)).WillByDefault(Return(true));
84 ON_CALL(*netlink_utils_, GetInterfaces(_, _))
85 .WillByDefault(Invoke(bind(
86 MockGetInterfacesResponse, mock_interfaces, true, _1, _2)));
87 }
88
89 NiceMock<MockInterfaceTool>* if_tool_ = new NiceMock<MockInterfaceTool>;
90
91 unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
92 new NiceMock<MockNetlinkManager>()};
93
94 unique_ptr<NiceMock<MockNetlinkUtils>> netlink_utils_{
95 new NiceMock<MockNetlinkUtils>(netlink_manager_.get())};
96 unique_ptr<NiceMock<MockScanUtils>> scan_utils_{
97 new NiceMock<MockScanUtils>(netlink_manager_.get())};
98 const vector<InterfaceInfo> mock_interfaces = {
99 // Client interface
100 InterfaceInfo(
101 kFakeInterfaceIndex,
102 std::string(kFakeInterfaceName),
103 std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddress)),
104 // AP Interface
105 InterfaceInfo(
106 kFakeInterfaceIndex1,
107 std::string(kFakeInterfaceName1),
108 std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddress1)),
109 // p2p interface
110 InterfaceInfo(
111 kFakeInterfaceIndexP2p,
112 std::string(kFakeInterfaceNameP2p),
113 std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddressP2p))
114 };
115
116 Server server_{unique_ptr<InterfaceTool>(if_tool_),
117 netlink_utils_.get(),
118 scan_utils_.get()};
119 }; // class ServerTest
120
121 } // namespace
122
TEST_F(ServerTest,CanSetUpApInterface)123 TEST_F(ServerTest, CanSetUpApInterface) {
124 sp<IApInterface> ap_if;
125 EXPECT_CALL(*netlink_utils_, SubscribeRegDomainChange(_, _));
126
127 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &ap_if).isOk());
128 EXPECT_NE(nullptr, ap_if.get());
129 }
130
TEST_F(ServerTest,CanSupportMultipleInterfaces)131 TEST_F(ServerTest, CanSupportMultipleInterfaces) {
132 sp<IApInterface> ap_if;
133
134 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &ap_if).isOk());
135 EXPECT_NE(nullptr, ap_if.get());
136
137 sp<IApInterface> second_ap_if;
138 // We won't throw on a second interface request.
139 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &second_ap_if).isOk());
140 // But this time we won't get an interface back.
141 EXPECT_NE(nullptr, second_ap_if.get());
142 }
143
TEST_F(ServerTest,CanDestroyInterfaces)144 TEST_F(ServerTest, CanDestroyInterfaces) {
145 sp<IApInterface> ap_if;
146
147 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &ap_if).isOk());
148
149 // When we tear down the interface, we expect the driver to be unloaded.
150 EXPECT_CALL(*netlink_utils_, UnsubscribeRegDomainChange(_));
151 EXPECT_TRUE(server_.tearDownInterfaces().isOk());
152 // After a tearDown, we should be able to create another interface.
153 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &ap_if).isOk());
154 }
155
TEST_F(ServerTest,CanTeardownApInterface)156 TEST_F(ServerTest, CanTeardownApInterface) {
157 sp<IApInterface> ap_if;
158
159 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &ap_if).isOk());
160 EXPECT_NE(nullptr, ap_if.get());
161
162 // Try to remove an invalid iface name, this should fail.
163 bool success = true;
164 EXPECT_TRUE(server_.tearDownApInterface(
165 kFateInterfaceNameInvalid, &success).isOk());
166 EXPECT_FALSE(success);
167
168 EXPECT_TRUE(server_.tearDownApInterface(kFakeInterfaceName, &success).isOk());
169 EXPECT_TRUE(success);
170 }
171
TEST_F(ServerTest,CanTeardownClientInterface)172 TEST_F(ServerTest, CanTeardownClientInterface) {
173 sp<IClientInterface> client_if;
174
175 EXPECT_TRUE(server_.createClientInterface(
176 kFakeInterfaceName, &client_if).isOk());
177 EXPECT_NE(nullptr, client_if.get());
178
179 // Try to remove an invalid iface name, this should fail.
180 bool success = true;
181 EXPECT_TRUE(server_.tearDownClientInterface(
182 kFateInterfaceNameInvalid, &success).isOk());
183 EXPECT_FALSE(success);
184
185 EXPECT_TRUE(server_.tearDownClientInterface(
186 kFakeInterfaceName, &success).isOk());
187 EXPECT_TRUE(success);
188 }
189
TEST_F(ServerTest,CanCreateTeardownApAndClientInterface)190 TEST_F(ServerTest, CanCreateTeardownApAndClientInterface) {
191 sp<IClientInterface> client_if;
192 sp<IApInterface> ap_if;
193
194 EXPECT_TRUE(server_.createClientInterface(kFakeInterfaceName, &client_if).isOk());
195 EXPECT_NE(nullptr, client_if.get());
196
197 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName1, &ap_if).isOk());
198 EXPECT_NE(nullptr, ap_if.get());
199
200 bool success = true;
201 // Try to remove an invalid iface name, this should fail.
202 EXPECT_TRUE(server_.tearDownClientInterface(
203 kFateInterfaceNameInvalid, &success).isOk());
204 EXPECT_FALSE(success);
205 EXPECT_TRUE(server_.tearDownApInterface(
206 kFateInterfaceNameInvalid, &success).isOk());
207 EXPECT_FALSE(success);
208
209 EXPECT_TRUE(server_.tearDownClientInterface(
210 kFakeInterfaceName, &success).isOk());
211 EXPECT_TRUE(success);
212
213 EXPECT_TRUE(server_.tearDownApInterface(
214 kFakeInterfaceName1, &success).isOk());
215 EXPECT_TRUE(success);
216 }
217
TEST_F(ServerTest,CanDestroyApAndClientInterfaces)218 TEST_F(ServerTest, CanDestroyApAndClientInterfaces) {
219 sp<IClientInterface> client_if;
220 sp<IApInterface> ap_if;
221
222 EXPECT_TRUE(server_.createClientInterface(
223 kFakeInterfaceName, &client_if).isOk());
224 EXPECT_NE(nullptr, client_if.get());
225
226 EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName1, &ap_if).isOk());
227 EXPECT_NE(nullptr, ap_if.get());
228
229 // When we tear down the interfaces, we expect the iface to be unloaded.
230 EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceName), Eq(false))).Times(2);
231 EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceName1), Eq(false))).Times(2);
232 EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceNameP2p), Eq(false)));
233
234 EXPECT_TRUE(server_.tearDownInterfaces().isOk());
235 }
236 } // namespace wificond
237 } // namespace android
238