blob: bb25c543e04de054cbbebb8db2ec91e643060106 [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>
Peter Qiuf0731732014-11-11 09:46:41 -080023#include <gmock/gmock.h>
24#include <gtest/gtest.h>
25
Peter Qiu7a420d32015-09-22 11:25:15 -070026#if !defined(__ANDROID__)
27#include <chromeos/dbus/service_constants.h>
28#else
29#include "dbus/apmanager/dbus-constants.h"
30#endif
31
Peter Qiufb39ba42014-11-21 09:09:59 -080032#include "apmanager/mock_device.h"
33#include "apmanager/mock_manager.h"
34
Peter Qiu8e785b92014-11-24 10:01:08 -080035using ::testing::_;
Peter Qiufb39ba42014-11-21 09:09:59 -080036using ::testing::Mock;
37using ::testing::Return;
Peter Qiu8e785b92014-11-24 10:01:08 -080038using ::testing::SetArgumentPointee;
Peter Qiuf0731732014-11-11 09:46:41 -080039namespace apmanager {
40
41namespace {
42
43const char kServicePath[] = "/manager/services/0";
44const char kSsid[] = "TestSsid";
45const char kInterface[] = "uap0";
Peter Qiu68303292014-12-10 10:42:13 -080046const char kBridgeInterface[] = "br0";
Peter Qiubfd410e2015-01-09 15:14:20 -080047const char kControlInterfacePath[] = "/var/run/apmanager/hostapd/ctrl_iface";
Peter Qiuf0731732014-11-11 09:46:41 -080048const char kPassphrase[] = "Passphrase";
Peter Qiu8e785b92014-11-24 10:01:08 -080049const char k24GHzHTCapab[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
50const char k5GHzHTCapab[] =
51 "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";
52
Peter Qiuf0731732014-11-11 09:46:41 -080053const uint16_t k24GHzChannel = 6;
54const uint16_t k5GHzChannel = 36;
55
56const char kExpected80211gConfigContent[] = "ssid=TestSsid\n"
57 "channel=6\n"
Peter Qiuf0731732014-11-11 09:46:41 -080058 "interface=uap0\n"
Peter Qiu8e785b92014-11-24 10:01:08 -080059 "hw_mode=g\n"
Peter Qiuf0731732014-11-11 09:46:41 -080060 "driver=nl80211\n"
61 "fragm_threshold=2346\n"
62 "rts_threshold=2347\n";
63
Peter Qiu68303292014-12-10 10:42:13 -080064const char kExpected80211gBridgeConfigContent[] = "ssid=TestSsid\n"
65 "bridge=br0\n"
66 "channel=6\n"
67 "interface=uap0\n"
68 "hw_mode=g\n"
69 "driver=nl80211\n"
70 "fragm_threshold=2346\n"
71 "rts_threshold=2347\n";
72
Peter Qiubfd410e2015-01-09 15:14:20 -080073const char kExpected80211gCtrlIfaceConfigContent[] =
74 "ssid=TestSsid\n"
75 "channel=6\n"
76 "interface=uap0\n"
77 "hw_mode=g\n"
78 "ctrl_interface=/var/run/apmanager/hostapd/ctrl_iface\n"
79 "ctrl_interface_group=apmanager\n"
80 "driver=nl80211\n"
81 "fragm_threshold=2346\n"
82 "rts_threshold=2347\n";
83
Peter Qiu8e785b92014-11-24 10:01:08 -080084const char kExpected80211n5GHzConfigContent[] =
85 "ssid=TestSsid\n"
86 "channel=36\n"
87 "interface=uap0\n"
88 "ieee80211n=1\n"
89 "ht_capab=[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]\n"
90 "hw_mode=a\n"
91 "driver=nl80211\n"
92 "fragm_threshold=2346\n"
93 "rts_threshold=2347\n";
Peter Qiuf0731732014-11-11 09:46:41 -080094
Peter Qiu8e785b92014-11-24 10:01:08 -080095const char kExpected80211n24GHzConfigContent[] =
96 "ssid=TestSsid\n"
97 "channel=6\n"
98 "interface=uap0\n"
99 "ieee80211n=1\n"
100 "ht_capab=[LDPC SMPS-STATIC GF SHORT-GI-20]\n"
101 "hw_mode=g\n"
102 "driver=nl80211\n"
103 "fragm_threshold=2346\n"
104 "rts_threshold=2347\n";
Peter Qiuf0731732014-11-11 09:46:41 -0800105
106const char kExpectedRsnConfigContent[] = "ssid=TestSsid\n"
107 "channel=6\n"
Peter Qiuf0731732014-11-11 09:46:41 -0800108 "interface=uap0\n"
Peter Qiu8e785b92014-11-24 10:01:08 -0800109 "hw_mode=g\n"
Peter Qiuf0731732014-11-11 09:46:41 -0800110 "wpa=2\n"
111 "rsn_pairwise=CCMP\n"
112 "wpa_key_mgmt=WPA-PSK\n"
113 "wpa_passphrase=Passphrase\n"
114 "driver=nl80211\n"
115 "fragm_threshold=2346\n"
116 "rts_threshold=2347\n";
117
118} // namespace
119
120class ConfigTest : public testing::Test {
121 public:
Peter Qiufb39ba42014-11-21 09:09:59 -0800122 ConfigTest() : config_(&manager_, kServicePath) {}
123
124 void SetupDevice(const std::string& interface) {
125 // Setup mock device.
Peter Qiu8e785b92014-11-24 10:01:08 -0800126 device_ = new MockDevice();
127 device_->SetPreferredApInterface(interface);
Peter Qiufb39ba42014-11-21 09:09:59 -0800128 EXPECT_CALL(manager_, GetDeviceFromInterfaceName(interface))
Peter Qiu8e785b92014-11-24 10:01:08 -0800129 .WillRepeatedly(Return(device_));
Peter Qiufb39ba42014-11-21 09:09:59 -0800130 }
Peter Qiuf0731732014-11-11 09:46:41 -0800131
132 protected:
133 Config config_;
Peter Qiufb39ba42014-11-21 09:09:59 -0800134 MockManager manager_;
Peter Qiu8e785b92014-11-24 10:01:08 -0800135 scoped_refptr<MockDevice> device_;
Peter Qiuf0731732014-11-11 09:46:41 -0800136};
137
Peter Qiu376e4042014-11-13 09:40:28 -0800138MATCHER_P(IsConfigErrorStartingWith, message, "") {
Peter Qiuf0731732014-11-11 09:46:41 -0800139 return arg != nullptr &&
Alex Vakulenkoe8f58982015-06-15 12:53:22 -0700140 arg->GetDomain() == chromeos::errors::dbus::kDomain &&
141 arg->GetCode() == kConfigError &&
142 base::StartsWithASCII(arg->GetMessage(), message, false);
Peter Qiuf0731732014-11-11 09:46:41 -0800143}
144
Peter Qiu8e785b92014-11-24 10:01:08 -0800145TEST_F(ConfigTest, GetFrequencyFromChannel) {
146 uint32_t frequency;
147 // Invalid channel.
148 EXPECT_FALSE(Config::GetFrequencyFromChannel(0, &frequency));
149 EXPECT_FALSE(Config::GetFrequencyFromChannel(166, &frequency));
150 EXPECT_FALSE(Config::GetFrequencyFromChannel(14, &frequency));
151 EXPECT_FALSE(Config::GetFrequencyFromChannel(33, &frequency));
152
153 // Valid channel.
154 const uint32_t kChannel1Frequency = 2412;
155 const uint32_t kChannel13Frequency = 2472;
156 const uint32_t kChannel34Frequency = 5170;
157 const uint32_t kChannel165Frequency = 5825;
158 EXPECT_TRUE(Config::GetFrequencyFromChannel(1, &frequency));
159 EXPECT_EQ(kChannel1Frequency, frequency);
160 EXPECT_TRUE(Config::GetFrequencyFromChannel(13, &frequency));
161 EXPECT_EQ(kChannel13Frequency, frequency);
162 EXPECT_TRUE(Config::GetFrequencyFromChannel(34, &frequency));
163 EXPECT_EQ(kChannel34Frequency, frequency);
164 EXPECT_TRUE(Config::GetFrequencyFromChannel(165, &frequency));
165 EXPECT_EQ(kChannel165Frequency, frequency);
166}
167
Peter Qiu68303292014-12-10 10:42:13 -0800168TEST_F(ConfigTest, ValidateSsid) {
169 chromeos::ErrorPtr error;
170 // SSID must contain between 1 and 32 characters.
171 EXPECT_TRUE(config_.ValidateSsid(&error, "s"));
172 EXPECT_TRUE(config_.ValidateSsid(&error, std::string(32, 'c')));
173 EXPECT_FALSE(config_.ValidateSsid(&error, ""));
174 EXPECT_FALSE(config_.ValidateSsid(&error, std::string(33, 'c')));
175}
176
177TEST_F(ConfigTest, ValidateSecurityMode) {
178 chromeos::ErrorPtr error;
179 EXPECT_TRUE(config_.ValidateSecurityMode(&error, kSecurityModeNone));
180 EXPECT_TRUE(config_.ValidateSecurityMode(&error, kSecurityModeRSN));
181 EXPECT_FALSE(config_.ValidateSecurityMode(&error, "InvalidSecurityMode"));
182}
183
184TEST_F(ConfigTest, ValidatePassphrase) {
185 chromeos::ErrorPtr error;
186 // Passpharse must contain between 8 and 63 characters.
187 EXPECT_TRUE(config_.ValidatePassphrase(&error, std::string(8, 'c')));
188 EXPECT_TRUE(config_.ValidatePassphrase(&error, std::string(63, 'c')));
189 EXPECT_FALSE(config_.ValidatePassphrase(&error, std::string(7, 'c')));
190 EXPECT_FALSE(config_.ValidatePassphrase(&error, std::string(64, 'c')));
191}
192
193TEST_F(ConfigTest, ValidateHwMode) {
194 chromeos::ErrorPtr error;
195 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211a));
196 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211b));
197 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211g));
198 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211n));
199 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211ac));
200 EXPECT_FALSE(config_.ValidateSecurityMode(&error, "InvalidHwMode"));
201}
202
203TEST_F(ConfigTest, ValidateOperationMode) {
204 chromeos::ErrorPtr error;
205 EXPECT_TRUE(config_.ValidateOperationMode(&error, kOperationModeServer));
206 EXPECT_TRUE(config_.ValidateOperationMode(&error, kOperationModeBridge));
207 EXPECT_FALSE(config_.ValidateOperationMode(&error, "InvalidMode"));
208}
209
210TEST_F(ConfigTest, ValidateChannel) {
211 chromeos::ErrorPtr error;
212 EXPECT_TRUE(config_.ValidateChannel(&error, 1));
213 EXPECT_TRUE(config_.ValidateChannel(&error, 13));
214 EXPECT_TRUE(config_.ValidateChannel(&error, 34));
215 EXPECT_TRUE(config_.ValidateChannel(&error, 165));
216 EXPECT_FALSE(config_.ValidateChannel(&error, 0));
217 EXPECT_FALSE(config_.ValidateChannel(&error, 14));
218 EXPECT_FALSE(config_.ValidateChannel(&error, 33));
219 EXPECT_FALSE(config_.ValidateChannel(&error, 166));
220}
221
Peter Qiuf0731732014-11-11 09:46:41 -0800222TEST_F(ConfigTest, NoSsid) {
223 config_.SetChannel(k24GHzChannel);
224 config_.SetHwMode(kHwMode80211g);
225 config_.SetInterfaceName(kInterface);
226
227 std::string config_content;
228 chromeos::ErrorPtr error;
229 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
Peter Qiu376e4042014-11-13 09:40:28 -0800230 EXPECT_THAT(error, IsConfigErrorStartingWith("SSID not specified"));
Peter Qiuf0731732014-11-11 09:46:41 -0800231}
232
Peter Qiufb39ba42014-11-21 09:09:59 -0800233TEST_F(ConfigTest, NoInterface) {
234 // Basic 80211.g configuration.
235 config_.SetSsid(kSsid);
236 config_.SetChannel(k24GHzChannel);
237 config_.SetHwMode(kHwMode80211g);
238
239 // No device available, fail to generate config file.
240 chromeos::ErrorPtr error;
241 std::string config_content;
242 EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(nullptr));
243 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
244 EXPECT_THAT(error, IsConfigErrorStartingWith("No device available"));
245 Mock::VerifyAndClearExpectations(&manager_);
246
247 // Device available, config file should be generated without any problem.
248 scoped_refptr<MockDevice> device = new MockDevice();
249 device->SetPreferredApInterface(kInterface);
250 chromeos::ErrorPtr error1;
251 EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(device));
252 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content));
253 EXPECT_NE(std::string::npos, config_content.find(
254 kExpected80211gConfigContent))
255 << "Expected to find the following config...\n"
256 << kExpected80211gConfigContent << "..within content...\n"
257 << config_content;
258 EXPECT_EQ(nullptr, error1.get());
259 Mock::VerifyAndClearExpectations(&manager_);
260}
261
Peter Qiu68303292014-12-10 10:42:13 -0800262TEST_F(ConfigTest, InvalidInterface) {
263 // Basic 80211.g configuration.
264 config_.SetSsid(kSsid);
265 config_.SetChannel(k24GHzChannel);
266 config_.SetHwMode(kHwMode80211g);
267 config_.SetInterfaceName(kInterface);
268
269 // No device available, fail to generate config file.
270 chromeos::ErrorPtr error;
271 std::string config_content;
272 EXPECT_CALL(manager_, GetDeviceFromInterfaceName(kInterface))
273 .WillOnce(Return(nullptr));
274 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
275 EXPECT_THAT(error,
276 IsConfigErrorStartingWith(
277 "Unable to find device for the specified interface"));
278 Mock::VerifyAndClearExpectations(&manager_);
279}
280
281TEST_F(ConfigTest, BridgeMode) {
282 config_.SetSsid(kSsid);
283 config_.SetChannel(k24GHzChannel);
284 config_.SetHwMode(kHwMode80211g);
285 config_.SetInterfaceName(kInterface);
286 config_.SetOperationMode(kOperationModeBridge);
287
288 // Bridge interface required for bridge mode.
289 chromeos::ErrorPtr error;
290 std::string config_content;
291 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
292 EXPECT_THAT(error,
293 IsConfigErrorStartingWith("Bridge interface not specified"));
294
295 // Set bridge interface, config file should be generated without error.
296 config_.SetBridgeInterface(kBridgeInterface);
297 // Setup mock device.
298 SetupDevice(kInterface);
299 chromeos::ErrorPtr error1;
300 std::string config_content1;
301 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content1));
302 EXPECT_NE(std::string::npos, config_content1.find(
303 kExpected80211gBridgeConfigContent))
304 << "Expected to find the following config...\n"
305 << kExpected80211gBridgeConfigContent << "..within content...\n"
306 << config_content1;
307 EXPECT_EQ(nullptr, error1.get());
308}
309
Peter Qiuf0731732014-11-11 09:46:41 -0800310TEST_F(ConfigTest, 80211gConfig) {
311 config_.SetSsid(kSsid);
312 config_.SetChannel(k24GHzChannel);
313 config_.SetHwMode(kHwMode80211g);
314 config_.SetInterfaceName(kInterface);
315
Peter Qiufb39ba42014-11-21 09:09:59 -0800316 // Setup mock device.
317 SetupDevice(kInterface);
318
Peter Qiuf0731732014-11-11 09:46:41 -0800319 std::string config_content;
320 chromeos::ErrorPtr error;
321 EXPECT_TRUE(config_.GenerateConfigFile(&error, &config_content));
322 EXPECT_NE(std::string::npos, config_content.find(
323 kExpected80211gConfigContent))
324 << "Expected to find the following config...\n"
325 << kExpected80211gConfigContent << "..within content...\n"
326 << config_content;
327 EXPECT_EQ(nullptr, error.get());
328}
329
Peter Qiubfd410e2015-01-09 15:14:20 -0800330TEST_F(ConfigTest, 80211gConfigWithControlInterface) {
331 config_.SetSsid(kSsid);
332 config_.SetChannel(k24GHzChannel);
333 config_.SetHwMode(kHwMode80211g);
334 config_.SetInterfaceName(kInterface);
335 config_.set_control_interface(kControlInterfacePath);
336
337 // Setup mock device.
338 SetupDevice(kInterface);
339
340 std::string config_content;
341 chromeos::ErrorPtr error;
342 EXPECT_TRUE(config_.GenerateConfigFile(&error, &config_content));
343 EXPECT_NE(std::string::npos, config_content.find(
344 kExpected80211gCtrlIfaceConfigContent))
345 << "Expected to find the following config...\n"
346 << kExpected80211gCtrlIfaceConfigContent << "..within content...\n"
347 << config_content;
348 EXPECT_EQ(nullptr, error.get());
349}
350
Peter Qiuf0731732014-11-11 09:46:41 -0800351TEST_F(ConfigTest, 80211nConfig) {
352 config_.SetSsid(kSsid);
353 config_.SetHwMode(kHwMode80211n);
354 config_.SetInterfaceName(kInterface);
355
Peter Qiufb39ba42014-11-21 09:09:59 -0800356 // Setup mock device.
357 SetupDevice(kInterface);
358
Peter Qiuf0731732014-11-11 09:46:41 -0800359 // 5GHz channel.
360 config_.SetChannel(k5GHzChannel);
361 std::string ghz5_config_content;
362 chromeos::ErrorPtr error;
Peter Qiu8e785b92014-11-24 10:01:08 -0800363 std::string ht_capab_5ghz(k5GHzHTCapab);
364 EXPECT_CALL(*device_.get(), GetHTCapability(k5GHzChannel, _))
365 .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_5ghz), Return(true)));
Peter Qiuf0731732014-11-11 09:46:41 -0800366 EXPECT_TRUE(config_.GenerateConfigFile(&error, &ghz5_config_content));
367 EXPECT_NE(std::string::npos, ghz5_config_content.find(
368 kExpected80211n5GHzConfigContent))
369 << "Expected to find the following config...\n"
370 << kExpected80211n5GHzConfigContent << "..within content...\n"
371 << ghz5_config_content;
372 EXPECT_EQ(nullptr, error.get());
Peter Qiu8e785b92014-11-24 10:01:08 -0800373 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiuf0731732014-11-11 09:46:41 -0800374
375 // 2.4GHz channel.
376 config_.SetChannel(k24GHzChannel);
377 std::string ghz24_config_content;
378 chromeos::ErrorPtr error1;
Peter Qiu8e785b92014-11-24 10:01:08 -0800379 std::string ht_capab_24ghz(k24GHzHTCapab);
380 EXPECT_CALL(*device_.get(), GetHTCapability(k24GHzChannel, _))
381 .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_24ghz), Return(true)));
Peter Qiuf0731732014-11-11 09:46:41 -0800382 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &ghz24_config_content));
383 EXPECT_NE(std::string::npos, ghz24_config_content.find(
384 kExpected80211n24GHzConfigContent))
385 << "Expected to find the following config...\n"
386 << kExpected80211n24GHzConfigContent << "..within content...\n"
387 << ghz24_config_content;
388 EXPECT_EQ(nullptr, error.get());
Peter Qiu8e785b92014-11-24 10:01:08 -0800389 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiuf0731732014-11-11 09:46:41 -0800390}
391
392TEST_F(ConfigTest, RsnConfig) {
393 config_.SetSsid(kSsid);
394 config_.SetChannel(k24GHzChannel);
395 config_.SetHwMode(kHwMode80211g);
396 config_.SetInterfaceName(kInterface);
397 config_.SetSecurityMode(kSecurityModeRSN);
398
Peter Qiufb39ba42014-11-21 09:09:59 -0800399 // Setup mock device.
400 SetupDevice(kInterface);
401
Peter Qiuf0731732014-11-11 09:46:41 -0800402 // Failed due to no passphrase specified.
403 std::string config_content;
404 chromeos::ErrorPtr error;
405 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
Peter Qiu376e4042014-11-13 09:40:28 -0800406 EXPECT_THAT(error, IsConfigErrorStartingWith(
Peter Qiuf0731732014-11-11 09:46:41 -0800407 base::StringPrintf("Passphrase not set for security mode: %s",
408 kSecurityModeRSN)));
409
410 chromeos::ErrorPtr error1;
411 config_.SetPassphrase(kPassphrase);
412 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content));
413 EXPECT_NE(std::string::npos, config_content.find(
414 kExpectedRsnConfigContent))
415 << "Expected to find the following config...\n"
416 << kExpectedRsnConfigContent << "..within content...\n"
417 << config_content;
418 EXPECT_EQ(nullptr, error1.get());
419}
420
421} // namespace apmanager