blob: 74c7859b4096eb18620edc151bd5f426002214ea [file] [log] [blame]
Peter Qiuf0731732014-11-11 09:46:41 -08001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "apmanager/config.h"
6
Peter Qiufb39ba42014-11-21 09:09:59 -08007#include <string>
8
Peter Qiuf0731732014-11-11 09:46:41 -08009#include <base/strings/string_util.h>
10#include <base/strings/stringprintf.h>
11#include <chromeos/dbus/service_constants.h>
12#include <gmock/gmock.h>
13#include <gtest/gtest.h>
14
Peter Qiufb39ba42014-11-21 09:09:59 -080015#include "apmanager/mock_device.h"
16#include "apmanager/mock_manager.h"
17
Peter Qiu8e785b92014-11-24 10:01:08 -080018using ::testing::_;
Peter Qiufb39ba42014-11-21 09:09:59 -080019using ::testing::Mock;
20using ::testing::Return;
Peter Qiu8e785b92014-11-24 10:01:08 -080021using ::testing::SetArgumentPointee;
Peter Qiuf0731732014-11-11 09:46:41 -080022namespace apmanager {
23
24namespace {
25
26const char kServicePath[] = "/manager/services/0";
27const char kSsid[] = "TestSsid";
28const char kInterface[] = "uap0";
Peter Qiu68303292014-12-10 10:42:13 -080029const char kBridgeInterface[] = "br0";
Peter Qiuf0731732014-11-11 09:46:41 -080030const char kPassphrase[] = "Passphrase";
Peter Qiu8e785b92014-11-24 10:01:08 -080031const char k24GHzHTCapab[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
32const char k5GHzHTCapab[] =
33 "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";
34
Peter Qiuf0731732014-11-11 09:46:41 -080035const uint16_t k24GHzChannel = 6;
36const uint16_t k5GHzChannel = 36;
37
38const char kExpected80211gConfigContent[] = "ssid=TestSsid\n"
39 "channel=6\n"
Peter Qiuf0731732014-11-11 09:46:41 -080040 "interface=uap0\n"
Peter Qiu8e785b92014-11-24 10:01:08 -080041 "hw_mode=g\n"
Peter Qiuf0731732014-11-11 09:46:41 -080042 "driver=nl80211\n"
43 "fragm_threshold=2346\n"
44 "rts_threshold=2347\n";
45
Peter Qiu68303292014-12-10 10:42:13 -080046const char kExpected80211gBridgeConfigContent[] = "ssid=TestSsid\n"
47 "bridge=br0\n"
48 "channel=6\n"
49 "interface=uap0\n"
50 "hw_mode=g\n"
51 "driver=nl80211\n"
52 "fragm_threshold=2346\n"
53 "rts_threshold=2347\n";
54
Peter Qiu8e785b92014-11-24 10:01:08 -080055const char kExpected80211n5GHzConfigContent[] =
56 "ssid=TestSsid\n"
57 "channel=36\n"
58 "interface=uap0\n"
59 "ieee80211n=1\n"
60 "ht_capab=[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]\n"
61 "hw_mode=a\n"
62 "driver=nl80211\n"
63 "fragm_threshold=2346\n"
64 "rts_threshold=2347\n";
Peter Qiuf0731732014-11-11 09:46:41 -080065
Peter Qiu8e785b92014-11-24 10:01:08 -080066const char kExpected80211n24GHzConfigContent[] =
67 "ssid=TestSsid\n"
68 "channel=6\n"
69 "interface=uap0\n"
70 "ieee80211n=1\n"
71 "ht_capab=[LDPC SMPS-STATIC GF SHORT-GI-20]\n"
72 "hw_mode=g\n"
73 "driver=nl80211\n"
74 "fragm_threshold=2346\n"
75 "rts_threshold=2347\n";
Peter Qiuf0731732014-11-11 09:46:41 -080076
77const char kExpectedRsnConfigContent[] = "ssid=TestSsid\n"
78 "channel=6\n"
Peter Qiuf0731732014-11-11 09:46:41 -080079 "interface=uap0\n"
Peter Qiu8e785b92014-11-24 10:01:08 -080080 "hw_mode=g\n"
Peter Qiuf0731732014-11-11 09:46:41 -080081 "wpa=2\n"
82 "rsn_pairwise=CCMP\n"
83 "wpa_key_mgmt=WPA-PSK\n"
84 "wpa_passphrase=Passphrase\n"
85 "driver=nl80211\n"
86 "fragm_threshold=2346\n"
87 "rts_threshold=2347\n";
88
89} // namespace
90
91class ConfigTest : public testing::Test {
92 public:
Peter Qiufb39ba42014-11-21 09:09:59 -080093 ConfigTest() : config_(&manager_, kServicePath) {}
94
95 void SetupDevice(const std::string& interface) {
96 // Setup mock device.
Peter Qiu8e785b92014-11-24 10:01:08 -080097 device_ = new MockDevice();
98 device_->SetPreferredApInterface(interface);
Peter Qiufb39ba42014-11-21 09:09:59 -080099 EXPECT_CALL(manager_, GetDeviceFromInterfaceName(interface))
Peter Qiu8e785b92014-11-24 10:01:08 -0800100 .WillRepeatedly(Return(device_));
Peter Qiufb39ba42014-11-21 09:09:59 -0800101 }
Peter Qiuf0731732014-11-11 09:46:41 -0800102
103 protected:
104 Config config_;
Peter Qiufb39ba42014-11-21 09:09:59 -0800105 MockManager manager_;
Peter Qiu8e785b92014-11-24 10:01:08 -0800106 scoped_refptr<MockDevice> device_;
Peter Qiuf0731732014-11-11 09:46:41 -0800107};
108
Peter Qiu376e4042014-11-13 09:40:28 -0800109MATCHER_P(IsConfigErrorStartingWith, message, "") {
Peter Qiuf0731732014-11-11 09:46:41 -0800110 return arg != nullptr &&
111 arg->GetDomain() == chromeos::errors::dbus::kDomain &&
112 arg->GetCode() == kConfigError &&
Peter Qiu376e4042014-11-13 09:40:28 -0800113 StartsWithASCII(arg->GetMessage(), message, false);
Peter Qiuf0731732014-11-11 09:46:41 -0800114}
115
Peter Qiu8e785b92014-11-24 10:01:08 -0800116TEST_F(ConfigTest, GetFrequencyFromChannel) {
117 uint32_t frequency;
118 // Invalid channel.
119 EXPECT_FALSE(Config::GetFrequencyFromChannel(0, &frequency));
120 EXPECT_FALSE(Config::GetFrequencyFromChannel(166, &frequency));
121 EXPECT_FALSE(Config::GetFrequencyFromChannel(14, &frequency));
122 EXPECT_FALSE(Config::GetFrequencyFromChannel(33, &frequency));
123
124 // Valid channel.
125 const uint32_t kChannel1Frequency = 2412;
126 const uint32_t kChannel13Frequency = 2472;
127 const uint32_t kChannel34Frequency = 5170;
128 const uint32_t kChannel165Frequency = 5825;
129 EXPECT_TRUE(Config::GetFrequencyFromChannel(1, &frequency));
130 EXPECT_EQ(kChannel1Frequency, frequency);
131 EXPECT_TRUE(Config::GetFrequencyFromChannel(13, &frequency));
132 EXPECT_EQ(kChannel13Frequency, frequency);
133 EXPECT_TRUE(Config::GetFrequencyFromChannel(34, &frequency));
134 EXPECT_EQ(kChannel34Frequency, frequency);
135 EXPECT_TRUE(Config::GetFrequencyFromChannel(165, &frequency));
136 EXPECT_EQ(kChannel165Frequency, frequency);
137}
138
Peter Qiu68303292014-12-10 10:42:13 -0800139TEST_F(ConfigTest, ValidateSsid) {
140 chromeos::ErrorPtr error;
141 // SSID must contain between 1 and 32 characters.
142 EXPECT_TRUE(config_.ValidateSsid(&error, "s"));
143 EXPECT_TRUE(config_.ValidateSsid(&error, std::string(32, 'c')));
144 EXPECT_FALSE(config_.ValidateSsid(&error, ""));
145 EXPECT_FALSE(config_.ValidateSsid(&error, std::string(33, 'c')));
146}
147
148TEST_F(ConfigTest, ValidateSecurityMode) {
149 chromeos::ErrorPtr error;
150 EXPECT_TRUE(config_.ValidateSecurityMode(&error, kSecurityModeNone));
151 EXPECT_TRUE(config_.ValidateSecurityMode(&error, kSecurityModeRSN));
152 EXPECT_FALSE(config_.ValidateSecurityMode(&error, "InvalidSecurityMode"));
153}
154
155TEST_F(ConfigTest, ValidatePassphrase) {
156 chromeos::ErrorPtr error;
157 // Passpharse must contain between 8 and 63 characters.
158 EXPECT_TRUE(config_.ValidatePassphrase(&error, std::string(8, 'c')));
159 EXPECT_TRUE(config_.ValidatePassphrase(&error, std::string(63, 'c')));
160 EXPECT_FALSE(config_.ValidatePassphrase(&error, std::string(7, 'c')));
161 EXPECT_FALSE(config_.ValidatePassphrase(&error, std::string(64, 'c')));
162}
163
164TEST_F(ConfigTest, ValidateHwMode) {
165 chromeos::ErrorPtr error;
166 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211a));
167 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211b));
168 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211g));
169 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211n));
170 EXPECT_TRUE(config_.ValidateHwMode(&error, kHwMode80211ac));
171 EXPECT_FALSE(config_.ValidateSecurityMode(&error, "InvalidHwMode"));
172}
173
174TEST_F(ConfigTest, ValidateOperationMode) {
175 chromeos::ErrorPtr error;
176 EXPECT_TRUE(config_.ValidateOperationMode(&error, kOperationModeServer));
177 EXPECT_TRUE(config_.ValidateOperationMode(&error, kOperationModeBridge));
178 EXPECT_FALSE(config_.ValidateOperationMode(&error, "InvalidMode"));
179}
180
181TEST_F(ConfigTest, ValidateChannel) {
182 chromeos::ErrorPtr error;
183 EXPECT_TRUE(config_.ValidateChannel(&error, 1));
184 EXPECT_TRUE(config_.ValidateChannel(&error, 13));
185 EXPECT_TRUE(config_.ValidateChannel(&error, 34));
186 EXPECT_TRUE(config_.ValidateChannel(&error, 165));
187 EXPECT_FALSE(config_.ValidateChannel(&error, 0));
188 EXPECT_FALSE(config_.ValidateChannel(&error, 14));
189 EXPECT_FALSE(config_.ValidateChannel(&error, 33));
190 EXPECT_FALSE(config_.ValidateChannel(&error, 166));
191}
192
Peter Qiuf0731732014-11-11 09:46:41 -0800193TEST_F(ConfigTest, NoSsid) {
194 config_.SetChannel(k24GHzChannel);
195 config_.SetHwMode(kHwMode80211g);
196 config_.SetInterfaceName(kInterface);
197
198 std::string config_content;
199 chromeos::ErrorPtr error;
200 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
Peter Qiu376e4042014-11-13 09:40:28 -0800201 EXPECT_THAT(error, IsConfigErrorStartingWith("SSID not specified"));
Peter Qiuf0731732014-11-11 09:46:41 -0800202}
203
Peter Qiufb39ba42014-11-21 09:09:59 -0800204TEST_F(ConfigTest, NoInterface) {
205 // Basic 80211.g configuration.
206 config_.SetSsid(kSsid);
207 config_.SetChannel(k24GHzChannel);
208 config_.SetHwMode(kHwMode80211g);
209
210 // No device available, fail to generate config file.
211 chromeos::ErrorPtr error;
212 std::string config_content;
213 EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(nullptr));
214 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
215 EXPECT_THAT(error, IsConfigErrorStartingWith("No device available"));
216 Mock::VerifyAndClearExpectations(&manager_);
217
218 // Device available, config file should be generated without any problem.
219 scoped_refptr<MockDevice> device = new MockDevice();
220 device->SetPreferredApInterface(kInterface);
221 chromeos::ErrorPtr error1;
222 EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(device));
223 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content));
224 EXPECT_NE(std::string::npos, config_content.find(
225 kExpected80211gConfigContent))
226 << "Expected to find the following config...\n"
227 << kExpected80211gConfigContent << "..within content...\n"
228 << config_content;
229 EXPECT_EQ(nullptr, error1.get());
230 Mock::VerifyAndClearExpectations(&manager_);
231}
232
Peter Qiu68303292014-12-10 10:42:13 -0800233TEST_F(ConfigTest, InvalidInterface) {
234 // Basic 80211.g configuration.
235 config_.SetSsid(kSsid);
236 config_.SetChannel(k24GHzChannel);
237 config_.SetHwMode(kHwMode80211g);
238 config_.SetInterfaceName(kInterface);
239
240 // No device available, fail to generate config file.
241 chromeos::ErrorPtr error;
242 std::string config_content;
243 EXPECT_CALL(manager_, GetDeviceFromInterfaceName(kInterface))
244 .WillOnce(Return(nullptr));
245 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
246 EXPECT_THAT(error,
247 IsConfigErrorStartingWith(
248 "Unable to find device for the specified interface"));
249 Mock::VerifyAndClearExpectations(&manager_);
250}
251
252TEST_F(ConfigTest, BridgeMode) {
253 config_.SetSsid(kSsid);
254 config_.SetChannel(k24GHzChannel);
255 config_.SetHwMode(kHwMode80211g);
256 config_.SetInterfaceName(kInterface);
257 config_.SetOperationMode(kOperationModeBridge);
258
259 // Bridge interface required for bridge mode.
260 chromeos::ErrorPtr error;
261 std::string config_content;
262 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
263 EXPECT_THAT(error,
264 IsConfigErrorStartingWith("Bridge interface not specified"));
265
266 // Set bridge interface, config file should be generated without error.
267 config_.SetBridgeInterface(kBridgeInterface);
268 // Setup mock device.
269 SetupDevice(kInterface);
270 chromeos::ErrorPtr error1;
271 std::string config_content1;
272 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content1));
273 EXPECT_NE(std::string::npos, config_content1.find(
274 kExpected80211gBridgeConfigContent))
275 << "Expected to find the following config...\n"
276 << kExpected80211gBridgeConfigContent << "..within content...\n"
277 << config_content1;
278 EXPECT_EQ(nullptr, error1.get());
279}
280
Peter Qiuf0731732014-11-11 09:46:41 -0800281TEST_F(ConfigTest, 80211gConfig) {
282 config_.SetSsid(kSsid);
283 config_.SetChannel(k24GHzChannel);
284 config_.SetHwMode(kHwMode80211g);
285 config_.SetInterfaceName(kInterface);
286
Peter Qiufb39ba42014-11-21 09:09:59 -0800287 // Setup mock device.
288 SetupDevice(kInterface);
289
Peter Qiuf0731732014-11-11 09:46:41 -0800290 std::string config_content;
291 chromeos::ErrorPtr error;
292 EXPECT_TRUE(config_.GenerateConfigFile(&error, &config_content));
293 EXPECT_NE(std::string::npos, config_content.find(
294 kExpected80211gConfigContent))
295 << "Expected to find the following config...\n"
296 << kExpected80211gConfigContent << "..within content...\n"
297 << config_content;
298 EXPECT_EQ(nullptr, error.get());
299}
300
301TEST_F(ConfigTest, 80211nConfig) {
302 config_.SetSsid(kSsid);
303 config_.SetHwMode(kHwMode80211n);
304 config_.SetInterfaceName(kInterface);
305
Peter Qiufb39ba42014-11-21 09:09:59 -0800306 // Setup mock device.
307 SetupDevice(kInterface);
308
Peter Qiuf0731732014-11-11 09:46:41 -0800309 // 5GHz channel.
310 config_.SetChannel(k5GHzChannel);
311 std::string ghz5_config_content;
312 chromeos::ErrorPtr error;
Peter Qiu8e785b92014-11-24 10:01:08 -0800313 std::string ht_capab_5ghz(k5GHzHTCapab);
314 EXPECT_CALL(*device_.get(), GetHTCapability(k5GHzChannel, _))
315 .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_5ghz), Return(true)));
Peter Qiuf0731732014-11-11 09:46:41 -0800316 EXPECT_TRUE(config_.GenerateConfigFile(&error, &ghz5_config_content));
317 EXPECT_NE(std::string::npos, ghz5_config_content.find(
318 kExpected80211n5GHzConfigContent))
319 << "Expected to find the following config...\n"
320 << kExpected80211n5GHzConfigContent << "..within content...\n"
321 << ghz5_config_content;
322 EXPECT_EQ(nullptr, error.get());
Peter Qiu8e785b92014-11-24 10:01:08 -0800323 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiuf0731732014-11-11 09:46:41 -0800324
325 // 2.4GHz channel.
326 config_.SetChannel(k24GHzChannel);
327 std::string ghz24_config_content;
328 chromeos::ErrorPtr error1;
Peter Qiu8e785b92014-11-24 10:01:08 -0800329 std::string ht_capab_24ghz(k24GHzHTCapab);
330 EXPECT_CALL(*device_.get(), GetHTCapability(k24GHzChannel, _))
331 .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_24ghz), Return(true)));
Peter Qiuf0731732014-11-11 09:46:41 -0800332 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &ghz24_config_content));
333 EXPECT_NE(std::string::npos, ghz24_config_content.find(
334 kExpected80211n24GHzConfigContent))
335 << "Expected to find the following config...\n"
336 << kExpected80211n24GHzConfigContent << "..within content...\n"
337 << ghz24_config_content;
338 EXPECT_EQ(nullptr, error.get());
Peter Qiu8e785b92014-11-24 10:01:08 -0800339 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiuf0731732014-11-11 09:46:41 -0800340}
341
342TEST_F(ConfigTest, RsnConfig) {
343 config_.SetSsid(kSsid);
344 config_.SetChannel(k24GHzChannel);
345 config_.SetHwMode(kHwMode80211g);
346 config_.SetInterfaceName(kInterface);
347 config_.SetSecurityMode(kSecurityModeRSN);
348
Peter Qiufb39ba42014-11-21 09:09:59 -0800349 // Setup mock device.
350 SetupDevice(kInterface);
351
Peter Qiuf0731732014-11-11 09:46:41 -0800352 // Failed due to no passphrase specified.
353 std::string config_content;
354 chromeos::ErrorPtr error;
355 EXPECT_FALSE(config_.GenerateConfigFile(&error, &config_content));
Peter Qiu376e4042014-11-13 09:40:28 -0800356 EXPECT_THAT(error, IsConfigErrorStartingWith(
Peter Qiuf0731732014-11-11 09:46:41 -0800357 base::StringPrintf("Passphrase not set for security mode: %s",
358 kSecurityModeRSN)));
359
360 chromeos::ErrorPtr error1;
361 config_.SetPassphrase(kPassphrase);
362 EXPECT_TRUE(config_.GenerateConfigFile(&error1, &config_content));
363 EXPECT_NE(std::string::npos, config_content.find(
364 kExpectedRsnConfigContent))
365 << "Expected to find the following config...\n"
366 << kExpectedRsnConfigContent << "..within content...\n"
367 << config_content;
368 EXPECT_EQ(nullptr, error1.get());
369}
370
371} // namespace apmanager