Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(339)

Side by Side Diff: chromeos/network/network_connection_handler_unittest.cc

Issue 2861883002: [CrOS Tether] Transform NetworkConnectionHandler to an interface. (Closed)
Patch Set: stevenjb@ comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium 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 "chromeos/network/network_connection_handler.h"
6
7 #include <map>
8 #include <memory>
9 #include <set>
10
11 #include "base/bind.h"
12 #include "base/files/file_util.h"
13 #include "base/json/json_reader.h"
14 #include "base/macros.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/test/scoped_task_scheduler.h"
19 #include "chromeos/cert_loader.h"
20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/network/managed_network_configuration_handler_impl.h"
22 #include "chromeos/network/network_configuration_handler.h"
23 #include "chromeos/network/network_connection_observer.h"
24 #include "chromeos/network/network_profile_handler.h"
25 #include "chromeos/network/network_state_handler.h"
26 #include "chromeos/network/network_state_test.h"
27 #include "chromeos/network/onc/onc_utils.h"
28 #include "components/onc/onc_constants.h"
29 #include "crypto/scoped_nss_types.h"
30 #include "crypto/scoped_test_nss_db.h"
31 #include "net/base/net_errors.h"
32 #include "net/cert/nss_cert_database_chromeos.h"
33 #include "net/cert/x509_certificate.h"
34 #include "net/test/cert_test_util.h"
35 #include "net/test/test_data_directory.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "third_party/cros_system_api/dbus/service_constants.h"
38
39 namespace chromeos {
40
41 namespace {
42
43 const char kSuccessResult[] = "success";
44
45 const char kTetherGuid[] = "tether-guid";
46
47 class TestNetworkConnectionObserver : public NetworkConnectionObserver {
48 public:
49 TestNetworkConnectionObserver() {}
50 ~TestNetworkConnectionObserver() override {}
51
52 // NetworkConnectionObserver
53 void ConnectToNetworkRequested(const std::string& service_path) override {
54 requests_.insert(service_path);
55 }
56
57 void ConnectSucceeded(const std::string& service_path) override {
58 results_[service_path] = kSuccessResult;
59 }
60
61 void ConnectFailed(const std::string& service_path,
62 const std::string& error_name) override {
63 results_[service_path] = error_name;
64 }
65
66 void DisconnectRequested(const std::string& service_path) override {
67 requests_.insert(service_path);
68 }
69
70 bool GetRequested(const std::string& service_path) {
71 return requests_.count(service_path) != 0;
72 }
73
74 std::string GetResult(const std::string& service_path) {
75 auto iter = results_.find(service_path);
76 if (iter == results_.end())
77 return "";
78 return iter->second;
79 }
80
81 private:
82 std::set<std::string> requests_;
83 std::map<std::string, std::string> results_;
84
85 DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver);
86 };
87
88 class FakeTetherDelegate : public NetworkConnectionHandler::TetherDelegate {
89 public:
90 FakeTetherDelegate() {}
91 ~FakeTetherDelegate() override {}
92
93 void ConnectToNetwork(
94 const std::string& service_path,
95 const base::Closure& success_callback,
96 const network_handler::StringResultCallback& error_callback) override {
97 last_service_path_ = service_path;
98 last_success_callback_ = success_callback;
99 last_error_callback_ = error_callback;
100 }
101
102 std::string& last_service_path() { return last_service_path_; }
103
104 base::Closure& last_success_callback() { return last_success_callback_; }
105
106 network_handler::StringResultCallback& last_error_callback() {
107 return last_error_callback_;
108 }
109
110 private:
111 std::string last_service_path_;
112 base::Closure last_success_callback_;
113 network_handler::StringResultCallback last_error_callback_;
114 };
115
116 } // namespace
117
118 class NetworkConnectionHandlerTest : public NetworkStateTest {
119 public:
120 NetworkConnectionHandlerTest() : scoped_task_scheduler_(&message_loop_) {}
121
122 ~NetworkConnectionHandlerTest() override {}
123
124 void SetUp() override {
125 ASSERT_TRUE(test_nssdb_.is_open());
126
127 // Use the same DB for public and private slot.
128 test_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
129 crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())),
130 crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot()))));
131 test_nsscertdb_->SetSlowTaskRunnerForTest(message_loop_.task_runner());
132
133 CertLoader::Initialize();
134 CertLoader::ForceHardwareBackedForTesting();
135
136 DBusThreadManager::Initialize();
137
138 NetworkStateTest::SetUp();
139
140 LoginState::Initialize();
141
142 network_config_handler_.reset(
143 NetworkConfigurationHandler::InitializeForTest(
144 network_state_handler(), nullptr /* network_device_handler */));
145
146 network_profile_handler_.reset(new NetworkProfileHandler());
147 network_profile_handler_->Init();
148
149 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl());
150 managed_config_handler_->Init(
151 network_state_handler(), network_profile_handler_.get(),
152 network_config_handler_.get(), nullptr /* network_device_handler */,
153 nullptr /* prohibited_tecnologies_handler */);
154
155 network_connection_handler_.reset(new NetworkConnectionHandler);
156 network_connection_handler_->Init(network_state_handler(),
157 network_config_handler_.get(),
158 managed_config_handler_.get());
159 network_connection_observer_.reset(new TestNetworkConnectionObserver);
160 network_connection_handler_->AddObserver(
161 network_connection_observer_.get());
162
163 base::RunLoop().RunUntilIdle();
164
165 fake_tether_delegate_.reset(new FakeTetherDelegate());
166 }
167
168 void TearDown() override {
169 ShutdownNetworkState();
170
171 managed_config_handler_.reset();
172 network_profile_handler_.reset();
173 network_connection_handler_->RemoveObserver(
174 network_connection_observer_.get());
175 network_connection_observer_.reset();
176 network_connection_handler_.reset();
177 network_config_handler_.reset();
178
179 NetworkStateTest::TearDown();
180
181 LoginState::Shutdown();
182
183 NetworkStateTest::TearDown();
184
185 DBusThreadManager::Shutdown();
186 CertLoader::Shutdown();
187 }
188
189 protected:
190 void Connect(const std::string& service_path) {
191 const bool check_error_state = true;
192 network_connection_handler_->ConnectToNetwork(
193 service_path,
194 base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
195 base::Unretained(this)),
196 base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
197 base::Unretained(this)),
198 check_error_state);
199 base::RunLoop().RunUntilIdle();
200 }
201
202 void Disconnect(const std::string& service_path) {
203 network_connection_handler_->DisconnectNetwork(
204 service_path,
205 base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
206 base::Unretained(this)),
207 base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
208 base::Unretained(this)));
209 base::RunLoop().RunUntilIdle();
210 }
211
212 void SuccessCallback() {
213 result_ = kSuccessResult;
214 }
215
216 void ErrorCallback(const std::string& error_name,
217 std::unique_ptr<base::DictionaryValue> error_data) {
218 result_ = error_name;
219 }
220
221 std::string GetResultAndReset() {
222 std::string result;
223 result.swap(result_);
224 return result;
225 }
226
227 void StartCertLoader() {
228 CertLoader::Get()->StartWithNSSDB(test_nsscertdb_.get());
229 base::RunLoop().RunUntilIdle();
230 }
231
232 void LoginToRegularUser() {
233 LoginState::Get()->SetLoggedInState(LoginState::LOGGED_IN_ACTIVE,
234 LoginState::LOGGED_IN_USER_REGULAR);
235 base::RunLoop().RunUntilIdle();
236 }
237
238 scoped_refptr<net::X509Certificate> ImportTestClientCert() {
239 net::CertificateList ca_cert_list(net::CreateCertificateListFromFile(
240 net::GetTestCertsDirectory(), "client_1_ca.pem",
241 net::X509Certificate::FORMAT_AUTO));
242 if (ca_cert_list.empty()) {
243 LOG(ERROR) << "No CA cert loaded.";
244 return nullptr;
245 }
246 net::NSSCertDatabase::ImportCertFailureList failures;
247 EXPECT_TRUE(test_nsscertdb_->ImportCACerts(
248 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures));
249 if (!failures.empty()) {
250 LOG(ERROR) << net::ErrorToString(failures[0].net_error);
251 return nullptr;
252 }
253
254 // Import a client cert signed by that CA.
255 scoped_refptr<net::X509Certificate> client_cert(
256 net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(),
257 "client_1.pem", "client_1.pk8",
258 test_nssdb_.slot()));
259 return client_cert;
260 }
261
262 void SetupPolicy(const std::string& network_configs_json,
263 const base::DictionaryValue& global_config,
264 bool user_policy) {
265 std::string error;
266 std::unique_ptr<base::Value> network_configs_value =
267 base::JSONReader::ReadAndReturnError(network_configs_json,
268 base::JSON_ALLOW_TRAILING_COMMAS,
269 nullptr, &error);
270 ASSERT_TRUE(network_configs_value) << error;
271
272 base::ListValue* network_configs = nullptr;
273 ASSERT_TRUE(network_configs_value->GetAsList(&network_configs));
274
275 if (user_policy) {
276 managed_config_handler_->SetPolicy(::onc::ONC_SOURCE_USER_POLICY,
277 kUserHash, *network_configs,
278 global_config);
279 } else {
280 managed_config_handler_->SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY,
281 std::string(), // no username hash
282 *network_configs,
283 global_config);
284 }
285 base::RunLoop().RunUntilIdle();
286 }
287
288 std::unique_ptr<NetworkConfigurationHandler> network_config_handler_;
289 std::unique_ptr<NetworkConnectionHandler> network_connection_handler_;
290 std::unique_ptr<TestNetworkConnectionObserver> network_connection_observer_;
291 std::unique_ptr<ManagedNetworkConfigurationHandlerImpl>
292 managed_config_handler_;
293 std::unique_ptr<NetworkProfileHandler> network_profile_handler_;
294 crypto::ScopedTestNSSDB test_nssdb_;
295 std::unique_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
296 base::MessageLoopForUI message_loop_;
297 std::string result_;
298 std::unique_ptr<FakeTetherDelegate> fake_tether_delegate_;
299
300 private:
301 base::test::ScopedTaskScheduler scoped_task_scheduler_;
302
303 DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest);
304 };
305
306 namespace {
307
308 const char* kNoNetwork = "no-network";
309 const char* kWifi0 = "wifi0";
310 const char* kWifi1 = "wifi1";
311 const char* kWifi2 = "wifi2";
312 const char* kWifi3 = "wifi3";
313
314 const char* kConfigConnectable =
315 "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\", "
316 " \"Connectable\": true }";
317 const char* kConfigConnected =
318 "{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"online\" }";
319 const char* kConfigConnecting =
320 "{ \"GUID\": \"wifi2\", \"Type\": \"wifi\", \"State\": \"association\" }";
321 const char* kConfigRequiresPassphrase =
322 "{ \"GUID\": \"wifi3\", \"Type\": \"wifi\", "
323 " \"PassphraseRequired\": true }";
324
325 const char* kPolicyWifi0 =
326 "[{ \"GUID\": \"wifi0\", \"IPAddressConfigType\": \"DHCP\", "
327 " \"Type\": \"WiFi\", \"Name\": \"My WiFi Network\","
328 " \"WiFi\": { \"SSID\": \"wifi0\"}}]";
329
330 } // namespace
331
332 TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectSuccess) {
333 EXPECT_FALSE(ConfigureService(kConfigConnectable).empty());
334 Connect(kWifi0);
335 EXPECT_EQ(kSuccessResult, GetResultAndReset());
336 EXPECT_EQ(shill::kStateOnline,
337 GetServiceStringProperty(kWifi0, shill::kStateProperty));
338 // Observer expectations
339 EXPECT_TRUE(network_connection_observer_->GetRequested(kWifi0));
340 EXPECT_EQ(kSuccessResult, network_connection_observer_->GetResult(kWifi0));
341 }
342
343 TEST_F(NetworkConnectionHandlerTest,
344 NetworkConnectionHandlerConnectProhibited) {
345 EXPECT_FALSE(ConfigureService(kConfigConnectable).empty());
346 base::DictionaryValue global_config;
347 global_config.SetBooleanWithoutPathExpansion(
348 ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, true);
349 SetupPolicy("[]", global_config, false /* load as device policy */);
350 LoginToRegularUser();
351 Connect(kWifi0);
352 EXPECT_EQ(NetworkConnectionHandler::kErrorUnmanagedNetwork,
353 GetResultAndReset());
354
355 SetupPolicy(kPolicyWifi0, global_config, false /* load as device policy */);
356 Connect(kWifi0);
357 EXPECT_EQ(kSuccessResult, GetResultAndReset());
358 }
359
360 // Handles basic failure cases.
361 TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectFailure) {
362 Connect(kNoNetwork);
363 EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
364 GetResultAndReset());
365 EXPECT_TRUE(network_connection_observer_->GetRequested(kNoNetwork));
366 EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
367 network_connection_observer_->GetResult(kNoNetwork));
368
369 EXPECT_FALSE(ConfigureService(kConfigConnected).empty());
370 Connect(kWifi1);
371 EXPECT_EQ(NetworkConnectionHandler::kErrorConnected, GetResultAndReset());
372 EXPECT_TRUE(network_connection_observer_->GetRequested(kWifi1));
373 EXPECT_EQ(NetworkConnectionHandler::kErrorConnected,
374 network_connection_observer_->GetResult(kWifi1));
375
376 EXPECT_FALSE(ConfigureService(kConfigConnecting).empty());
377 Connect(kWifi2);
378 EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting, GetResultAndReset());
379 EXPECT_TRUE(network_connection_observer_->GetRequested(kWifi2));
380 EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting,
381 network_connection_observer_->GetResult(kWifi2));
382
383 EXPECT_FALSE(ConfigureService(kConfigRequiresPassphrase).empty());
384 Connect(kWifi3);
385 EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
386 GetResultAndReset());
387 EXPECT_TRUE(network_connection_observer_->GetRequested(kWifi3));
388 EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
389 network_connection_observer_->GetResult(kWifi3));
390 }
391
392 namespace {
393
394 const char* kPolicyWithCertPatternTemplate =
395 "[ { \"GUID\": \"wifi4\","
396 " \"Name\": \"wifi4\","
397 " \"Type\": \"WiFi\","
398 " \"WiFi\": {"
399 " \"Security\": \"WPA-EAP\","
400 " \"SSID\": \"wifi_ssid\","
401 " \"EAP\": {"
402 " \"Outer\": \"EAP-TLS\","
403 " \"ClientCertType\": \"Pattern\","
404 " \"ClientCertPattern\": {"
405 " \"Subject\": {"
406 " \"CommonName\" : \"%s\""
407 " }"
408 " }"
409 " }"
410 " }"
411 "} ]";
412
413 } // namespace
414
415 // Handle certificates.
416 TEST_F(NetworkConnectionHandlerTest, ConnectCertificateMissing) {
417 StartCertLoader();
418 SetupPolicy(base::StringPrintf(kPolicyWithCertPatternTemplate, "unknown"),
419 base::DictionaryValue(), // no global config
420 true); // load as user policy
421
422 Connect("wifi4");
423 EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
424 GetResultAndReset());
425 }
426
427 TEST_F(NetworkConnectionHandlerTest, ConnectWithCertificateSuccess) {
428 StartCertLoader();
429 scoped_refptr<net::X509Certificate> cert = ImportTestClientCert();
430 ASSERT_TRUE(cert.get());
431
432 SetupPolicy(base::StringPrintf(kPolicyWithCertPatternTemplate,
433 cert->subject().common_name.c_str()),
434 base::DictionaryValue(), // no global config
435 true); // load as user policy
436
437 Connect("wifi4");
438 EXPECT_EQ(kSuccessResult, GetResultAndReset());
439 }
440
441 // Disabled, see http://crbug.com/396729.
442 TEST_F(NetworkConnectionHandlerTest,
443 DISABLED_ConnectWithCertificateRequestedBeforeCertsAreLoaded) {
444 scoped_refptr<net::X509Certificate> cert = ImportTestClientCert();
445 ASSERT_TRUE(cert.get());
446
447 SetupPolicy(base::StringPrintf(kPolicyWithCertPatternTemplate,
448 cert->subject().common_name.c_str()),
449 base::DictionaryValue(), // no global config
450 true); // load as user policy
451
452 Connect("wifi4");
453
454 // Connect request came before the cert loader loaded certificates, so the
455 // connect request should have been throttled until the certificates are
456 // loaded.
457 EXPECT_EQ("", GetResultAndReset());
458
459 StartCertLoader();
460
461 // |StartCertLoader| should have triggered certificate loading.
462 // When the certificates got loaded, the connection request should have
463 // proceeded and eventually succeeded.
464 EXPECT_EQ(kSuccessResult, GetResultAndReset());
465 }
466
467 TEST_F(NetworkConnectionHandlerTest,
468 NetworkConnectionHandlerDisconnectSuccess) {
469 EXPECT_FALSE(ConfigureService(kConfigConnected).empty());
470 Disconnect(kWifi1);
471 EXPECT_TRUE(network_connection_observer_->GetRequested(kWifi1));
472 EXPECT_EQ(kSuccessResult, GetResultAndReset());
473 }
474
475 TEST_F(NetworkConnectionHandlerTest,
476 NetworkConnectionHandlerDisconnectFailure) {
477 Connect(kNoNetwork);
478 EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
479 GetResultAndReset());
480
481 EXPECT_FALSE(ConfigureService(kConfigConnectable).empty());
482 Disconnect(kWifi0);
483 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
484 }
485
486 TEST_F(NetworkConnectionHandlerTest, ConnectToTetherNetwork_Success) {
487 network_state_handler()->SetTetherTechnologyState(
488 NetworkStateHandler::TECHNOLOGY_ENABLED);
489 network_state_handler()->AddTetherNetworkState(
490 kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
491 100 /* signal_strength */, true /* has_connected_to_host */);
492 network_connection_handler_->SetTetherDelegate(fake_tether_delegate_.get());
493
494 Connect(kTetherGuid /* service_path */);
495
496 EXPECT_EQ(kTetherGuid, fake_tether_delegate_->last_service_path());
497 fake_tether_delegate_->last_success_callback().Run();
498 EXPECT_EQ(kSuccessResult, GetResultAndReset());
499 EXPECT_TRUE(network_connection_observer_->GetRequested(kTetherGuid));
500 EXPECT_EQ(kSuccessResult,
501 network_connection_observer_->GetResult(kTetherGuid));
502 }
503
504 TEST_F(NetworkConnectionHandlerTest, ConnectToTetherNetwork_Failure) {
505 network_state_handler()->SetTetherTechnologyState(
506 NetworkStateHandler::TECHNOLOGY_ENABLED);
507 network_state_handler()->AddTetherNetworkState(
508 kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
509 100 /* signal_strength */, true /* has_connected_to_host */);
510 network_connection_handler_->SetTetherDelegate(fake_tether_delegate_.get());
511
512 Connect(kTetherGuid /* service_path */);
513
514 EXPECT_EQ(kTetherGuid, fake_tether_delegate_->last_service_path());
515 fake_tether_delegate_->last_error_callback().Run(
516 NetworkConnectionHandler::kErrorConnectFailed);
517 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset());
518 EXPECT_TRUE(network_connection_observer_->GetRequested(kTetherGuid));
519 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed,
520 network_connection_observer_->GetResult(kTetherGuid));
521 }
522
523 TEST_F(NetworkConnectionHandlerTest, ConnectToTetherNetwork_NoTetherDelegate) {
524 network_state_handler()->SetTetherTechnologyState(
525 NetworkStateHandler::TECHNOLOGY_ENABLED);
526 network_state_handler()->AddTetherNetworkState(
527 kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
528 100 /* signal_strength */, true /* has_connected_to_host */);
529
530 // Do not set a tether delegate.
531
532 Connect(kTetherGuid /* service_path */);
533
534 EXPECT_EQ(
535 NetworkConnectionHandler::kErrorTetherConnectionAttemptWithNoDelegate,
536 GetResultAndReset());
537 EXPECT_TRUE(network_connection_observer_->GetRequested(kTetherGuid));
538 EXPECT_EQ(
539 NetworkConnectionHandler::kErrorTetherConnectionAttemptWithNoDelegate,
540 network_connection_observer_->GetResult(kTetherGuid));
541 }
542
543 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/network/network_connection_handler_impl_unittest.cc ('k') | chromeos/network/network_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698