blob: 36aed9707852bb19cd4f97f1390f00878d4e3132 [file] [log] [blame]
Peter Qiu326b6cf2015-09-02 11:11:42 -07001//
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//
Peter Qiuf0731732014-11-11 09:46:41 -080016
17#include "apmanager/config.h"
18
Peter Qiufb39ba42014-11-21 09:09:59 -080019#include <string>
20
Peter Qiuf0731732014-11-11 09:46:41 -080021#include <base/strings/string_util.h>
22#include <base/strings/stringprintf.h>
23#include <chromeos/dbus/service_constants.h>
24#include <gmock/gmock.h>
25#include <gtest/gtest.h>
26
Peter Qiufb39ba42014-11-21 09:09:59 -080027#include "apmanager/mock_device.h"
28#include "apmanager/mock_manager.h"
29
Peter Qiu8e785b92014-11-24 10:01:08 -080030using ::testing::_;
Peter Qiufb39ba42014-11-21 09:09:59 -080031using ::testing::Mock;
32using ::testing::Return;
Peter Qiu8e785b92014-11-24 10:01:08 -080033using ::testing::SetArgumentPointee;
Peter Qiuf0731732014-11-11 09:46:41 -080034namespace apmanager {
35
36namespace {
37
38const char kServicePath[] = "/manager/services/0";
39const char kSsid[] = "TestSsid";
40const char kInterface[] = "uap0";
Peter Qiu68303292014-12-10 10:42:13 -080041const char kBridgeInterface[] = "br0";
Peter Qiubfd410e2015-01-09 15:14:20 -080042const char kControlInterfacePath[] = "/var/run/apmanager/hostapd/ctrl_iface";
Peter Qiuf0731732014-11-11 09:46:41 -080043const char kPassphrase[] = "Passphrase";
Peter Qiu8e785b92014-11-24 10:01:08 -080044const char k24GHzHTCapab[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
45const char k5GHzHTCapab[] =
46 "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";
47
Peter Qiuf0731732014-11-11 09:46:41 -080048const uint16_t k24GHzChannel = 6;
49const uint16_t k5GHzChannel = 36;
50
51const char kExpected80211gConfigContent[] = "ssid=TestSsid\n"
52 "channel=6\n"
Peter Qiuf0731732014-11-11 09:46:41 -080053 "interface=uap0\n"
Peter Qiu8e785b92014-11-24 10:01:08 -080054 "hw_mode=g\n"
Peter Qiuf0731732014-11-11 09:46:41 -080055 "driver=nl80211\n"
56 "fragm_threshold=2346\n"
57 "rts_threshold=2347\n";
58
Peter Qiu68303292014-12-10 10:42:13 -080059const char kExpected80211gBridgeConfigContent[] = "ssid=TestSsid\n"
60 "bridge=br0\n"
61 "channel=6\n"
62 "interface=uap0\n"
63 "hw_mode=g\n"
64 "driver=nl80211\n"
65 "fragm_threshold=2346\n"
66 "rts_threshold=2347\n";
67
Peter Qiubfd410e2015-01-09 15:14:20 -080068const char kExpected80211gCtrlIfaceConfigContent[] =
69 "ssid=TestSsid\n"
70 "channel=6\n"
71 "interface=uap0\n"
72 "hw_mode=g\n"
73 "ctrl_interface=/var/run/apmanager/hostapd/ctrl_iface\n"
74 "ctrl_interface_group=apmanager\n"
75 "driver=nl80211\n"
76 "fragm_threshold=2346\n"
77 "rts_threshold=2347\n";
78
Peter Qiu8e785b92014-11-24 10:01:08 -080079const char kExpected80211n5GHzConfigContent[] =
80 "ssid=TestSsid\n"
81 "channel=36\n"
82 "interface=uap0\n"
83 "ieee80211n=1\n"
84 "ht_capab=[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]\n"
85 "hw_mode=a\n"
86 "driver=nl80211\n"
87 "fragm_threshold=2346\n"
88 "rts_threshold=2347\n";
Peter Qiuf0731732014-11-11 09:46:41 -080089
Peter Qiu8e785b92014-11-24 10:01:08 -080090const char kExpected80211n24GHzConfigContent[] =
91 "ssid=TestSsid\n"
92 "channel=6\n"
93 "interface=uap0\n"
94 "ieee80211n=1\n"
95 "ht_capab=[LDPC SMPS-STATIC GF SHORT-GI-20]\n"
96 "hw_mode=g\n"
97 "driver=nl80211\n"
98 "fragm_threshold=2346\n"
99 "rts_threshold=2347\n";
Peter Qiuf0731732014-11-11 09:46:41 -0800100
101const char kExpectedRsnConfigContent[] = "ssid=TestSsid\n"
102 "channel=6\n"
Peter Qiuf0731732014-11-11 09:46:41 -0800103 "interface=uap0\n"
Peter Qiu8e785b92014-11-24 10:01:08 -0800104 "hw_mode=g\n"
Peter Qiuf0731732014-11-11 09:46:41 -0800105 "wpa=2\n"
106 "rsn_pairwise=CCMP\n"
107 "wpa_key_mgmt=WPA-PSK\n"
108 "wpa_passphrase=Passphrase\n"
109 "driver=nl80211\n"
110 "fragm_threshold=2346\n"
111 "rts_threshold=2347\n";
112
113} // namespace
114
115class ConfigTest : public testing::Test {
116 public:
Peter Qiufb39ba42014-11-21 09:09:59 -0800117 ConfigTest() : config_(&manager_, kServicePath) {}
118
119 void SetupDevice(const std::string& interface) {
120 // Setup mock device.
Peter Qiu8e785b92014-11-24 10:01:08 -0800121 device_ = new MockDevice();
122 device_->SetPreferredApInterface(interface);
Peter Qiufb39ba42014-11-21 09:09:59 -0800123 EXPECT_CALL(manager_, GetDeviceFromInterfaceName(interface))
Peter Qiu8e785b92014-11-24 10:01:08 -0800124 .WillRepeatedly(Return(device_));
Peter Qiufb39ba42014-11-21 09:09:59 -0800125 }
Peter Qiuf0731732014-11-11 09:46:41 -0800126
127 protected:
128 Config config_;
Peter Qiufb39ba42014-11-21 09:09:59 -0800129 MockManager manager_;
Peter Qiu8e785b92014-11-24 10:01:08 -0800130 scoped_refptr<MockDevice> device_;
Peter Qiuf0731732014-11-11 09:46:41 -0800131};
132
Peter Qiu376e4042014-11-13 09:40:28 -0800133MATCHER_P(IsConfigErrorStartingWith, message, "") {
Peter Qiuf0731732014-11-11 09:46:41 -0800134 return arg != nullptr &&
Alex Vakulenkoe8f58982015-06-15 12:53:22 -0700135 arg->GetDomain() == chromeos::errors::dbus::kDomain &&
136 arg->GetCode() == kConfigError &&
137 base::StartsWithASCII(arg->GetMessage(), message, false);
Peter Qiuf0731732014-11-11 09:46:41 -0800138}
139
Peter Qiu8e785b92014-11-24 10:01:08 -0800140TEST_F(ConfigTest, GetFrequencyFromChannel) {
141 uint32_t frequency;
142 // Invalid channel.
143 EXPECT_FALSE(Config::GetFrequencyFromChannel(0, &frequency));
144 EXPECT_FALSE(Config::GetFrequencyFromChannel(166, &frequency));
145 EXPECT_FALSE(Config::GetFrequencyFromChannel(14, &frequency));
146 EXPECT_FALSE(Config::GetFrequencyFromChannel(33, &frequency));
147
148 // Valid channel.
149 const uint32_t kChannel1Frequency = 2412;
150 const uint32_t kChannel13Frequency = 2472;
151 const uint32_t kChannel34Frequency = 5170;
152 const uint32_t kChannel165Frequency = 5825;
153 EXPECT_TRUE(Config::GetFrequencyFromChannel(1, &frequency));
154 EXPECT_EQ(kChannel1Frequency, frequency);
155 EXPECT_TRUE(Config::GetFrequencyFromChannel(13, &frequency));
156 EXPECT_EQ(kChannel13Frequency, frequency);
157 EXPECT_TRUE(Config::GetFrequencyFromChannel(34, &frequency));
158 EXPECT_EQ(kChannel34Frequency, frequency);
159 EXPECT_TRUE(Config::GetFrequencyFromChannel(165, &frequency));
160 EXPECT_EQ(kChannel165Frequency, frequency);
161}
162
Peter Qiu68303292014-12-10 10:42:13 -0800163TEST_F(ConfigTest, ValidateSsid) {
164 chromeos::ErrorPtr error;
165 // SSID must contain between 1 and 32 characters.
166 EXPECT_TRUE(config_.ValidateSsid(&error, "s"));
167 EXPECT_TRUE(config_.ValidateSsid(&error, std::string(32, 'c')));
168 EXPECT_FALSE(config_.ValidateSsid(&error, ""));
169 EXPECT_FALSE(config_.ValidateSsid(&error, std::string(33, 'c')));
170}
171
172TEST_F(ConfigTest, ValidateSecurityMode) {
173 chromeos::ErrorPtr error;
174 EXPECT_TRUE(config_.ValidateSecurityMode(&error, kSecurityModeNone));
175 EXPECT_TRUE(config_.ValidateSecurityMode(&error, kSecurityModeRSN));
176 EXPECT_FALSE(config_.ValidateSecurityMode(&error, "InvalidSecurityMode"));
177}
178
179TEST_F(ConfigTest, ValidatePassphrase) {
180 chromeos::ErrorPtr error;
181 // Passpharse must contain between 8 and 63 characters.
182 EXPECT_TRUE(config_.ValidatePassphrase(&error, std::string(8, 'c')));
183 EXPECT_TRUE(config_.ValidatePassphrase(&error, std::string(63, 'c')));
184 EXPECT_FALSE(config_.ValidatePassphrase(&error, std::string(7, 'c')));
185 EXPECT_FALSE(config_.ValidatePassphrase(&error, std::string(64, 'c')));
186}
187
188TEST_F(ConfigTest, ValidateHwMode) {
189 chromeos::ErrorPtr error;
190 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211a));
191 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211b));
192 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211g));
193 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211n));
194 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211ac));
195 EXPECT_FALSE(config_.ValidateSecurityMode(&error, "InvalidHwMode"));
196}
197
198TEST_F(ConfigTest, ValidateOperationMode) {
199 chromeos::ErrorPtr error;
200 EXPECT_TRUE(config_.ValidateOperationMode(&error, kOperationModeServer));
201 EXPECT_TRUE(config_.ValidateOperationMode(&error, kOperationModeBridge));
202 EXPECT_FALSE(config_.ValidateOperationMode(&error, "InvalidMode"));
203}
204
205TEST_F(ConfigTest, ValidateChannel) {
206 chromeos::ErrorPtr error;
207 EXPECT_TRUE(config_.ValidateChannel(&error, 1));
208 EXPECT_TRUE(config_.ValidateChannel(&error, 13));
209 EXPECT_TRUE(config_.ValidateChannel(&error, 34));
210 EXPECT_TRUE(config_.ValidateChannel(&error, 165));
211 EXPECT_FALSE(config_.ValidateChannel(&error, 0));
212 EXPECT_FALSE(config_.ValidateChannel(&error, 14));
213 EXPECT_FALSE(config_.ValidateChannel(&error, 33));
214 EXPECT_FALSE(config_.ValidateChannel(&error, 166));
215}
216
Peter Qiuf0731732014-11-11 09:46:41 -0800217TEST_F(ConfigTest, NoSsid) {
218 config_.SetChannel(k24GHzChannel);
219 config_.SetHwMode(kHwMode80211g);
220 config_.SetInterfaceName(kInterface);
221
222 std::string config_content;
223 chromeos::ErrorPtr error;
224 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
Peter Qiu376e4042014-11-13 09:40:28 -0800225 EXPECT_THAT(error, IsConfigErrorStartingWith("SSID not specified"));
Peter Qiuf0731732014-11-11 09:46:41 -0800226}
227
Peter Qiufb39ba42014-11-21 09:09:59 -0800228TEST_F(ConfigTest, NoInterface) {
229 // Basic 80211.g configuration.
230 config_.SetSsid(kSsid);
231 config_.SetChannel(k24GHzChannel);
232 config_.SetHwMode(kHwMode80211g);
233
234 // No device available, fail to generate config file.
235 chromeos::ErrorPtr error;
236 std::string config_content;
237 EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(nullptr));
238 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
239 EXPECT_THAT(error, IsConfigErrorStartingWith("No device available"));
240 Mock::VerifyAndClearExpectations(&manager_);
241
242 // Device available, config file should be generated without any problem.
243 scoped_refptr<MockDevice> device = new MockDevice();
244 device->SetPreferredApInterface(kInterface);
245 chromeos::ErrorPtr error1;
246 EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(device));
247 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content));
248 EXPECT_NE(std::string::npos, config_content.find(
249 kExpected80211gConfigContent))
250 << "Expected to find the following config...\n"
251 << kExpected80211gConfigContent << "..within content...\n"
252 << config_content;
253 EXPECT_EQ(nullptr, error1.get());
254 Mock::VerifyAndClearExpectations(&manager_);
255}
256
Peter Qiu68303292014-12-10 10:42:13 -0800257TEST_F(ConfigTest, InvalidInterface) {
258 // Basic 80211.g configuration.
259 config_.SetSsid(kSsid);
260 config_.SetChannel(k24GHzChannel);
261 config_.SetHwMode(kHwMode80211g);
262 config_.SetInterfaceName(kInterface);
263
264 // No device available, fail to generate config file.
265 chromeos::ErrorPtr error;
266 std::string config_content;
267 EXPECT_CALL(manager_, GetDeviceFromInterfaceName(kInterface))
268 .WillOnce(Return(nullptr));
269 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
270 EXPECT_THAT(error,
271 IsConfigErrorStartingWith(
272 "Unable to find device for the specified interface"));
273 Mock::VerifyAndClearExpectations(&manager_);
274}
275
276TEST_F(ConfigTest, BridgeMode) {
277 config_.SetSsid(kSsid);
278 config_.SetChannel(k24GHzChannel);
279 config_.SetHwMode(kHwMode80211g);
280 config_.SetInterfaceName(kInterface);
281 config_.SetOperationMode(kOperationModeBridge);
282
283 // Bridge interface required for bridge mode.
284 chromeos::ErrorPtr error;
285 std::string config_content;
286 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
287 EXPECT_THAT(error,
288 IsConfigErrorStartingWith("Bridge interface not specified"));
289
290 // Set bridge interface, config file should be generated without error.
291 config_.SetBridgeInterface(kBridgeInterface);
292 // Setup mock device.
293 SetupDevice(kInterface);
294 chromeos::ErrorPtr error1;
295 std::string config_content1;
296 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content1));
297 EXPECT_NE(std::string::npos, config_content1.find(
298 kExpected80211gBridgeConfigContent))
299 << "Expected to find the following config...\n"
300 << kExpected80211gBridgeConfigContent << "..within content...\n"
301 << config_content1;
302 EXPECT_EQ(nullptr, error1.get());
303}
304
Peter Qiuf0731732014-11-11 09:46:41 -0800305TEST_F(ConfigTest, 80211gConfig) {
306 config_.SetSsid(kSsid);
307 config_.SetChannel(k24GHzChannel);
308 config_.SetHwMode(kHwMode80211g);
309 config_.SetInterfaceName(kInterface);
310
Peter Qiufb39ba42014-11-21 09:09:59 -0800311 // Setup mock device.
312 SetupDevice(kInterface);
313
Peter Qiuf0731732014-11-11 09:46:41 -0800314 std::string config_content;
315 chromeos::ErrorPtr error;
316 EXPECT_TRUE(config_.GenerateConfigFile(&error, &config_content));
317 EXPECT_NE(std::string::npos, config_content.find(
318 kExpected80211gConfigContent))
319 << "Expected to find the following config...\n"
320 << kExpected80211gConfigContent << "..within content...\n"
321 << config_content;
322 EXPECT_EQ(nullptr, error.get());
323}
324
Peter Qiubfd410e2015-01-09 15:14:20 -0800325TEST_F(ConfigTest, 80211gConfigWithControlInterface) {
326 config_.SetSsid(kSsid);
327 config_.SetChannel(k24GHzChannel);
328 config_.SetHwMode(kHwMode80211g);
329 config_.SetInterfaceName(kInterface);
330 config_.set_control_interface(kControlInterfacePath);
331
332 // Setup mock device.
333 SetupDevice(kInterface);
334
335 std::string config_content;
336 chromeos::ErrorPtr error;
337 EXPECT_TRUE(config_.GenerateConfigFile(&error, &config_content));
338 EXPECT_NE(std::string::npos, config_content.find(
339 kExpected80211gCtrlIfaceConfigContent))
340 << "Expected to find the following config...\n"
341 << kExpected80211gCtrlIfaceConfigContent << "..within content...\n"
342 << config_content;
343 EXPECT_EQ(nullptr, error.get());
344}
345
Peter Qiuf0731732014-11-11 09:46:41 -0800346TEST_F(ConfigTest, 80211nConfig) {
347 config_.SetSsid(kSsid);
348 config_.SetHwMode(kHwMode80211n);
349 config_.SetInterfaceName(kInterface);
350
Peter Qiufb39ba42014-11-21 09:09:59 -0800351 // Setup mock device.
352 SetupDevice(kInterface);
353
Peter Qiuf0731732014-11-11 09:46:41 -0800354 // 5GHz channel.
355 config_.SetChannel(k5GHzChannel);
356 std::string ghz5_config_content;
357 chromeos::ErrorPtr error;
Peter Qiu8e785b92014-11-24 10:01:08 -0800358 std::string ht_capab_5ghz(k5GHzHTCapab);
359 EXPECT_CALL(*device_.get(), GetHTCapability(k5GHzChannel, _))
360 .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_5ghz), Return(true)));
Peter Qiuf0731732014-11-11 09:46:41 -0800361 EXPECT_TRUE(config_.GenerateConfigFile(&error, &ghz5_config_content));
362 EXPECT_NE(std::string::npos, ghz5_config_content.find(
363 kExpected80211n5GHzConfigContent))
364 << "Expected to find the following config...\n"
365 << kExpected80211n5GHzConfigContent << "..within content...\n"
366 << ghz5_config_content;
367 EXPECT_EQ(nullptr, error.get());
Peter Qiu8e785b92014-11-24 10:01:08 -0800368 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiuf0731732014-11-11 09:46:41 -0800369
370 // 2.4GHz channel.
371 config_.SetChannel(k24GHzChannel);
372 std::string ghz24_config_content;
373 chromeos::ErrorPtr error1;
Peter Qiu8e785b92014-11-24 10:01:08 -0800374 std::string ht_capab_24ghz(k24GHzHTCapab);
375 EXPECT_CALL(*device_.get(), GetHTCapability(k24GHzChannel, _))
376 .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_24ghz), Return(true)));
Peter Qiuf0731732014-11-11 09:46:41 -0800377 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &ghz24_config_content));
378 EXPECT_NE(std::string::npos, ghz24_config_content.find(
379 kExpected80211n24GHzConfigContent))
380 << "Expected to find the following config...\n"
381 << kExpected80211n24GHzConfigContent << "..within content...\n"
382 << ghz24_config_content;
383 EXPECT_EQ(nullptr, error.get());
Peter Qiu8e785b92014-11-24 10:01:08 -0800384 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiuf0731732014-11-11 09:46:41 -0800385}
386
387TEST_F(ConfigTest, RsnConfig) {
388 config_.SetSsid(kSsid);
389 config_.SetChannel(k24GHzChannel);
390 config_.SetHwMode(kHwMode80211g);
391 config_.SetInterfaceName(kInterface);
392 config_.SetSecurityMode(kSecurityModeRSN);
393
Peter Qiufb39ba42014-11-21 09:09:59 -0800394 // Setup mock device.
395 SetupDevice(kInterface);
396
Peter Qiuf0731732014-11-11 09:46:41 -0800397 // Failed due to no passphrase specified.
398 std::string config_content;
399 chromeos::ErrorPtr error;
400 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
Peter Qiu376e4042014-11-13 09:40:28 -0800401 EXPECT_THAT(error, IsConfigErrorStartingWith(
Peter Qiuf0731732014-11-11 09:46:41 -0800402 base::StringPrintf("Passphrase not set for security mode: %s",
403 kSecurityModeRSN)));
404
405 chromeos::ErrorPtr error1;
406 config_.SetPassphrase(kPassphrase);
407 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content));
408 EXPECT_NE(std::string::npos, config_content.find(
409 kExpectedRsnConfigContent))
410 << "Expected to find the following config...\n"
411 << kExpectedRsnConfigContent << "..within content...\n"
412 << config_content;
413 EXPECT_EQ(nullptr, error1.get());
414}
415
416} // namespace apmanager