- add sources.
[platform/framework/web/crosswalk.git] / src / chromeos / network / network_configuration_handler_unittest.cc
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 "base/bind.h"
6 #include "base/json/json_writer.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/string_piece.h"
9 #include "base/values.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "chromeos/dbus/mock_dbus_thread_manager.h"
12 #include "chromeos/dbus/mock_shill_manager_client.h"
13 #include "chromeos/dbus/mock_shill_profile_client.h"
14 #include "chromeos/dbus/mock_shill_service_client.h"
15 #include "chromeos/dbus/shill_stub_helper.h"
16 #include "chromeos/network/network_configuration_handler.h"
17 #include "chromeos/network/network_state.h"
18 #include "chromeos/network/network_state_handler.h"
19 #include "chromeos/network/network_state_handler_observer.h"
20 #include "chromeos/network/shill_property_util.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/cros_system_api/dbus/service_constants.h"
24
25 using ::testing::_;
26 using ::testing::Invoke;
27 using ::testing::Pointee;
28 using ::testing::Return;
29 using ::testing::SaveArg;
30 using ::testing::StrEq;
31
32 // Matcher to match base::Value.
33 MATCHER_P(IsEqualTo, value, "") { return arg.Equals(value); }
34
35 namespace chromeos {
36
37 namespace {
38
39 static std::string PrettyJson(const base::DictionaryValue& value) {
40   std::string pretty;
41   base::JSONWriter::WriteWithOptions(&value,
42                                      base::JSONWriter::OPTIONS_PRETTY_PRINT,
43                                      &pretty);
44   return pretty;
45 }
46
47 void DictionaryValueCallback(
48     const std::string& expected_id,
49     const std::string& expected_json,
50     const std::string& service_path,
51     const base::DictionaryValue& dictionary) {
52   std::string dict_str = PrettyJson(dictionary);
53   EXPECT_EQ(expected_json, dict_str);
54   EXPECT_EQ(expected_id, service_path);
55 }
56
57 void ErrorCallback(bool error_expected,
58                    const std::string& expected_id,
59                    const std::string& error_name,
60                    scoped_ptr<base::DictionaryValue> error_data) {
61   EXPECT_TRUE(error_expected) << "Unexpected error: " << error_name
62       << " with associated data: \n"
63       << PrettyJson(*error_data);
64 }
65
66 void StringResultCallback(const std::string& expected_result,
67                           const std::string& result) {
68   EXPECT_EQ(expected_result, result);
69 }
70
71 void DBusErrorCallback(const std::string& error_name,
72                        const std::string& error_message) {
73   EXPECT_TRUE(false) << "DBus Error: " << error_name << "("
74       << error_message << ")";
75 }
76
77 class TestCallback {
78  public:
79   TestCallback() : run_count_(0) {}
80   void Run() {
81     ++run_count_;
82   }
83   int run_count() const { return run_count_; }
84
85  private:
86   int run_count_;
87 };
88
89 }  // namespace
90
91 class NetworkConfigurationHandlerTest : public testing::Test {
92  public:
93   NetworkConfigurationHandlerTest()
94       : mock_manager_client_(NULL),
95         mock_profile_client_(NULL),
96         mock_service_client_(NULL),
97         dictionary_value_result_(NULL) {}
98   virtual ~NetworkConfigurationHandlerTest() {}
99
100   virtual void SetUp() OVERRIDE {
101     MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager;
102     EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus())
103     .WillRepeatedly(Return(reinterpret_cast<dbus::Bus*>(NULL)));
104     DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager);
105     mock_manager_client_ =
106         mock_dbus_thread_manager->mock_shill_manager_client();
107     mock_profile_client_ =
108         mock_dbus_thread_manager->mock_shill_profile_client();
109     mock_service_client_ =
110         mock_dbus_thread_manager->mock_shill_service_client();
111
112     network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
113     network_configuration_handler_.reset(new NetworkConfigurationHandler());
114     network_configuration_handler_->Init(network_state_handler_.get());
115     message_loop_.RunUntilIdle();
116   }
117
118   virtual void TearDown() OVERRIDE {
119     network_configuration_handler_.reset();
120     network_state_handler_.reset();
121     DBusThreadManager::Shutdown();
122   }
123
124   // Handles responses for GetProperties method calls.
125   void OnGetProperties(
126       const dbus::ObjectPath& path,
127       const ShillClientHelper::DictionaryValueCallback& callback) {
128     callback.Run(DBUS_METHOD_CALL_SUCCESS, *dictionary_value_result_);
129   }
130
131   // Handles responses for SetProperties method calls.
132   void OnSetProperties(const dbus::ObjectPath& service_path,
133                        const base::DictionaryValue& properties,
134                        const base::Closure& callback,
135                        const ShillClientHelper::ErrorCallback& error_callback) {
136     callback.Run();
137   }
138
139   // Handles responses for ClearProperties method calls.
140   void OnClearProperties(
141       const dbus::ObjectPath& service_path,
142       const std::vector<std::string>& names,
143       const ShillClientHelper::ListValueCallback& callback,
144       const ShillClientHelper::ErrorCallback& error_callback) {
145     base::ListValue result;
146     result.AppendBoolean(true);
147     callback.Run(result);
148   }
149
150   // Handles responses for ClearProperties method calls, and simulates an error
151   // result.
152   void OnClearPropertiesError(
153       const dbus::ObjectPath& service_path,
154       const std::vector<std::string>& names,
155       const ShillClientHelper::ListValueCallback& callback,
156       const ShillClientHelper::ErrorCallback& error_callback) {
157     base::ListValue result;
158     result.AppendBoolean(false);
159     callback.Run(result);
160   }
161
162   void OnConfigureService(
163       const dbus::ObjectPath& profile_path,
164       const base::DictionaryValue& properties,
165       const ObjectPathCallback& callback,
166       const ShillClientHelper::ErrorCallback& error_callback) {
167     callback.Run(dbus::ObjectPath("/service/2"));
168   }
169
170   void OnGetLoadableProfileEntries(
171       const dbus::ObjectPath& service_path,
172       const ShillClientHelper::DictionaryValueCallback& callback) {
173     base::DictionaryValue entries;
174     entries.SetString("profile1", "entry1");
175     entries.SetString("profile2", "entry2");
176     callback.Run(DBUS_METHOD_CALL_SUCCESS, entries);
177   }
178
179   void OnDeleteEntry(const dbus::ObjectPath& profile_path,
180                      const std::string& entry_path,
181                      const base::Closure& callback,
182                      const ShillClientHelper::ErrorCallback& error_callback) {
183     // Don't run the callback immediately to emulate actual behavior.
184     message_loop_.PostTask(FROM_HERE, callback);
185   }
186
187   bool PendingProfileEntryDeleterForTest(const std::string& service_path) {
188     return network_configuration_handler_->
189         PendingProfileEntryDeleterForTest(service_path);
190   }
191
192  protected:
193   MockShillManagerClient* mock_manager_client_;
194   MockShillProfileClient* mock_profile_client_;
195   MockShillServiceClient* mock_service_client_;
196   scoped_ptr<NetworkStateHandler> network_state_handler_;
197   scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
198   base::MessageLoopForUI message_loop_;
199   base::DictionaryValue* dictionary_value_result_;
200 };
201
202 TEST_F(NetworkConfigurationHandlerTest, GetProperties) {
203   std::string service_path = "/service/1";
204   std::string expected_json = "{\n   \"SSID\": \"MyNetwork\"\n}\n";
205   std::string networkName = "MyNetwork";
206   std::string key = "SSID";
207   scoped_ptr<base::StringValue> networkNameValue(
208       base::Value::CreateStringValue(networkName));
209
210   base::DictionaryValue value;
211   value.Set(key, base::Value::CreateStringValue(networkName));
212   dictionary_value_result_ = &value;
213   EXPECT_CALL(*mock_service_client_,
214               SetProperty(dbus::ObjectPath(service_path), key,
215                           IsEqualTo(networkNameValue.get()), _, _)).Times(1);
216   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
217       dbus::ObjectPath(service_path), key, *networkNameValue,
218       base::Bind(&base::DoNothing),
219       base::Bind(&DBusErrorCallback));
220   message_loop_.RunUntilIdle();
221
222   ShillServiceClient::DictionaryValueCallback get_properties_callback;
223   EXPECT_CALL(*mock_service_client_,
224               GetProperties(_, _)).WillOnce(
225                   Invoke(this,
226                          &NetworkConfigurationHandlerTest::OnGetProperties));
227   network_configuration_handler_->GetProperties(
228       service_path,
229       base::Bind(&DictionaryValueCallback,
230                  service_path,
231                  expected_json),
232                  base::Bind(&ErrorCallback, false, service_path));
233   message_loop_.RunUntilIdle();
234 }
235
236 TEST_F(NetworkConfigurationHandlerTest, SetProperties) {
237   std::string service_path = "/service/1";
238   std::string networkName = "MyNetwork";
239   std::string key = "SSID";
240   scoped_ptr<base::StringValue> networkNameValue(
241       base::Value::CreateStringValue(networkName));
242
243   base::DictionaryValue value;
244   value.Set(key, base::Value::CreateStringValue(networkName));
245   dictionary_value_result_ = &value;
246   EXPECT_CALL(*mock_service_client_,
247               SetProperties(_, _, _, _)).WillOnce(
248                   Invoke(this,
249                          &NetworkConfigurationHandlerTest::OnSetProperties));
250   network_configuration_handler_->SetProperties(
251       service_path,
252       value,
253       base::Bind(&base::DoNothing),
254       base::Bind(&ErrorCallback, false, service_path));
255   message_loop_.RunUntilIdle();
256 }
257
258 TEST_F(NetworkConfigurationHandlerTest, ClearProperties) {
259   std::string service_path = "/service/1";
260   std::string networkName = "MyNetwork";
261   std::string key = "SSID";
262   scoped_ptr<base::StringValue> networkNameValue(
263       base::Value::CreateStringValue(networkName));
264
265   // First set up a value to clear.
266   base::DictionaryValue value;
267   value.Set(key, base::Value::CreateStringValue(networkName));
268   dictionary_value_result_ = &value;
269   EXPECT_CALL(*mock_service_client_,
270               SetProperties(_, _, _, _)).WillOnce(
271                   Invoke(this,
272                          &NetworkConfigurationHandlerTest::OnSetProperties));
273   network_configuration_handler_->SetProperties(
274       service_path,
275       value,
276       base::Bind(&base::DoNothing),
277       base::Bind(&ErrorCallback, false, service_path));
278   message_loop_.RunUntilIdle();
279
280   // Now clear it.
281   std::vector<std::string> values_to_clear;
282   values_to_clear.push_back(key);
283   EXPECT_CALL(*mock_service_client_,
284               ClearProperties(_, _, _, _)).WillOnce(
285                   Invoke(this,
286                          &NetworkConfigurationHandlerTest::OnClearProperties));
287   network_configuration_handler_->ClearProperties(
288       service_path,
289       values_to_clear,
290       base::Bind(&base::DoNothing),
291       base::Bind(&ErrorCallback, false, service_path));
292   message_loop_.RunUntilIdle();
293 }
294
295 TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) {
296   std::string service_path = "/service/1";
297   std::string networkName = "MyNetwork";
298   std::string key = "SSID";
299   scoped_ptr<base::StringValue> networkNameValue(
300       base::Value::CreateStringValue(networkName));
301
302   // First set up a value to clear.
303   base::DictionaryValue value;
304   value.Set(key, base::Value::CreateStringValue(networkName));
305   dictionary_value_result_ = &value;
306   EXPECT_CALL(*mock_service_client_,
307               SetProperties(_, _, _, _)).WillOnce(
308                   Invoke(this,
309                          &NetworkConfigurationHandlerTest::OnSetProperties));
310   network_configuration_handler_->SetProperties(
311       service_path,
312       value,
313       base::Bind(&base::DoNothing),
314       base::Bind(&ErrorCallback, false, service_path));
315   message_loop_.RunUntilIdle();
316
317   // Now clear it.
318   std::vector<std::string> values_to_clear;
319   values_to_clear.push_back(key);
320   EXPECT_CALL(
321       *mock_service_client_,
322       ClearProperties(_, _, _, _)).WillOnce(
323           Invoke(this,
324                  &NetworkConfigurationHandlerTest::OnClearPropertiesError));
325   network_configuration_handler_->ClearProperties(
326       service_path,
327       values_to_clear,
328       base::Bind(&base::DoNothing),
329       base::Bind(&ErrorCallback, true, service_path));
330   message_loop_.RunUntilIdle();
331 }
332
333 TEST_F(NetworkConfigurationHandlerTest, CreateConfiguration) {
334   std::string networkName = "MyNetwork";
335   std::string key = "SSID";
336   std::string profile = "profile path";
337   base::DictionaryValue value;
338   shill_property_util::SetSSID(networkName, &value);
339   value.SetWithoutPathExpansion(shill::kProfileProperty,
340                                 base::Value::CreateStringValue(profile));
341
342   EXPECT_CALL(*mock_manager_client_,
343               ConfigureServiceForProfile(dbus::ObjectPath(profile), _, _, _))
344       .WillOnce(
345            Invoke(this, &NetworkConfigurationHandlerTest::OnConfigureService));
346   network_configuration_handler_->CreateConfiguration(
347       value,
348       base::Bind(&StringResultCallback, std::string("/service/2")),
349       base::Bind(&ErrorCallback, false, std::string("")));
350   message_loop_.RunUntilIdle();
351 }
352
353 TEST_F(NetworkConfigurationHandlerTest, RemoveConfiguration) {
354   std::string service_path = "/service/1";
355
356   TestCallback test_callback;
357   EXPECT_CALL(
358       *mock_service_client_,
359       GetLoadableProfileEntries(_, _)).WillOnce(Invoke(
360           this,
361           &NetworkConfigurationHandlerTest::OnGetLoadableProfileEntries));
362   EXPECT_CALL(
363       *mock_profile_client_,
364       DeleteEntry(_, _, _, _)).WillRepeatedly(Invoke(
365           this,
366           &NetworkConfigurationHandlerTest::OnDeleteEntry));
367
368   network_configuration_handler_->RemoveConfiguration(
369       service_path,
370       base::Bind(&TestCallback::Run, base::Unretained(&test_callback)),
371       base::Bind(&ErrorCallback, false, service_path));
372   message_loop_.RunUntilIdle();
373   EXPECT_EQ(1, test_callback.run_count());
374   EXPECT_FALSE(PendingProfileEntryDeleterForTest(service_path));
375 }
376
377 ////////////////////////////////////////////////////////////////////////////////
378 // Stub based tests
379
380 namespace {
381
382 class TestObserver : public chromeos::NetworkStateHandlerObserver {
383  public:
384   TestObserver() : network_list_changed_count_(0) {}
385   virtual ~TestObserver() {}
386
387   virtual void NetworkListChanged() OVERRIDE {
388     ++network_list_changed_count_;
389   }
390
391   virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE {
392     property_updates_[network->path()]++;
393   }
394
395   size_t network_list_changed_count() { return network_list_changed_count_; }
396
397   int PropertyUpdatesForService(const std::string& service_path) {
398     return property_updates_[service_path];
399   }
400
401   void ClearPropertyUpdates() {
402     property_updates_.clear();
403   }
404
405  private:
406   size_t network_list_changed_count_;
407   std::map<std::string, int> property_updates_;
408
409   DISALLOW_COPY_AND_ASSIGN(TestObserver);
410 };
411
412 }  // namespace
413
414 class NetworkConfigurationHandlerStubTest : public testing::Test {
415  public:
416   NetworkConfigurationHandlerStubTest()  {
417   }
418
419   virtual ~NetworkConfigurationHandlerStubTest() {
420   }
421
422   virtual void SetUp() OVERRIDE {
423     DBusThreadManager::InitializeWithStub();
424
425     network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
426     test_observer_.reset(new TestObserver());
427     network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE);
428
429     network_configuration_handler_.reset(new NetworkConfigurationHandler());
430     network_configuration_handler_->Init(network_state_handler_.get());
431
432     message_loop_.RunUntilIdle();
433     test_observer_->ClearPropertyUpdates();
434   }
435
436   virtual void TearDown() OVERRIDE {
437     network_configuration_handler_.reset();
438     network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE);
439     network_state_handler_.reset();
440     DBusThreadManager::Shutdown();
441   }
442
443   void SuccessCallback(const std::string& callback_name) {
444     success_callback_name_ = callback_name;
445   }
446
447   void GetPropertiesCallback(const std::string& service_path,
448                              const base::DictionaryValue& dictionary) {
449     get_properties_path_ = service_path;
450     get_properties_.reset(dictionary.DeepCopy());
451   }
452
453   void CreateConfigurationCallback(const std::string& service_path) {
454     create_service_path_ = service_path;
455   }
456
457  protected:
458   bool GetServiceStringProperty(const std::string& service_path,
459                                 const std::string& key,
460                                 std::string* result) {
461     ShillServiceClient::TestInterface* service_test =
462         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
463     const base::DictionaryValue* properties =
464         service_test->GetServiceProperties(service_path);
465     if (properties && properties->GetStringWithoutPathExpansion(key, result))
466       return true;
467     return false;
468   }
469
470   bool GetReceivedStringProperty(const std::string& service_path,
471                                  const std::string& key,
472                                  std::string* result) {
473     if (get_properties_path_ != service_path)
474       return false;
475     if (get_properties_ &&
476         get_properties_->GetStringWithoutPathExpansion(key, result))
477       return true;
478     return false;
479   }
480
481   scoped_ptr<NetworkStateHandler> network_state_handler_;
482   scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
483   scoped_ptr<TestObserver> test_observer_;
484   base::MessageLoopForUI message_loop_;
485   std::string success_callback_name_;
486   std::string get_properties_path_;
487   scoped_ptr<DictionaryValue> get_properties_;
488   std::string create_service_path_;
489 };
490
491 TEST_F(NetworkConfigurationHandlerStubTest, StubSetAndClearProperties) {
492   // TODO(stevenjb): Remove dependency on default Stub service.
493   const std::string service_path("wifi1");
494   const std::string test_identity("test_identity");
495   const std::string test_passphrase("test_passphrase");
496
497   // Set Properties
498   base::DictionaryValue properties_to_set;
499   properties_to_set.SetStringWithoutPathExpansion(
500       shill::kIdentityProperty, test_identity);
501   properties_to_set.SetStringWithoutPathExpansion(
502       shill::kPassphraseProperty, test_passphrase);
503   network_configuration_handler_->SetProperties(
504       service_path,
505       properties_to_set,
506       base::Bind(
507           &NetworkConfigurationHandlerStubTest::SuccessCallback,
508           base::Unretained(this), "SetProperties"),
509       base::Bind(&ErrorCallback, false, service_path));
510   message_loop_.RunUntilIdle();
511
512   EXPECT_EQ("SetProperties", success_callback_name_);
513   std::string identity, passphrase;
514   EXPECT_TRUE(GetServiceStringProperty(
515       service_path, shill::kIdentityProperty, &identity));
516   EXPECT_TRUE(GetServiceStringProperty(
517       service_path, shill::kPassphraseProperty, &passphrase));
518   EXPECT_EQ(test_identity, identity);
519   EXPECT_EQ(test_passphrase, passphrase);
520   EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(service_path));
521
522   // Clear Properties
523   std::vector<std::string> properties_to_clear;
524   properties_to_clear.push_back(shill::kIdentityProperty);
525   properties_to_clear.push_back(shill::kPassphraseProperty);
526   network_configuration_handler_->ClearProperties(
527       service_path,
528       properties_to_clear,
529       base::Bind(
530           &NetworkConfigurationHandlerStubTest::SuccessCallback,
531           base::Unretained(this), "ClearProperties"),
532       base::Bind(&ErrorCallback, false, service_path));
533   message_loop_.RunUntilIdle();
534
535   EXPECT_EQ("ClearProperties", success_callback_name_);
536   EXPECT_FALSE(GetServiceStringProperty(
537       service_path, shill::kIdentityProperty, &identity));
538   EXPECT_FALSE(GetServiceStringProperty(
539       service_path, shill::kIdentityProperty, &passphrase));
540   EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(service_path));
541 }
542
543 TEST_F(NetworkConfigurationHandlerStubTest, StubGetNameFromWifiHex) {
544   // TODO(stevenjb): Remove dependency on default Stub service.
545   const std::string service_path("wifi1");
546   std::string wifi_hex = "5468697320697320484558205353494421";
547   std::string expected_name = "This is HEX SSID!";
548
549   // Set Properties
550   base::DictionaryValue properties_to_set;
551   properties_to_set.SetStringWithoutPathExpansion(
552       shill::kWifiHexSsid, wifi_hex);
553   network_configuration_handler_->SetProperties(
554       service_path,
555       properties_to_set,
556       base::Bind(&base::DoNothing),
557       base::Bind(&ErrorCallback, false, service_path));
558   message_loop_.RunUntilIdle();
559   std::string wifi_hex_result;
560   EXPECT_TRUE(GetServiceStringProperty(
561       service_path, shill::kWifiHexSsid, &wifi_hex_result));
562   EXPECT_EQ(wifi_hex, wifi_hex_result);
563
564   // Get Properties
565   network_configuration_handler_->GetProperties(
566       service_path,
567       base::Bind(&NetworkConfigurationHandlerStubTest::GetPropertiesCallback,
568                  base::Unretained(this)),
569       base::Bind(&ErrorCallback, false, service_path));
570   message_loop_.RunUntilIdle();
571
572   EXPECT_EQ(service_path, get_properties_path_);
573   std::string name_result;
574   EXPECT_TRUE(GetReceivedStringProperty(
575       service_path, shill::kNameProperty, &name_result));
576   EXPECT_EQ(expected_name, name_result);
577 }
578
579 TEST_F(NetworkConfigurationHandlerStubTest, StubCreateConfiguration) {
580   const std::string service_path("test_wifi");
581   base::DictionaryValue properties;
582   shill_property_util::SetSSID(service_path, &properties);
583   properties.SetStringWithoutPathExpansion(shill::kNameProperty, service_path);
584   properties.SetStringWithoutPathExpansion(shill::kGuidProperty, service_path);
585   properties.SetStringWithoutPathExpansion(
586       shill::kTypeProperty, shill::kTypeWifi);
587   properties.SetStringWithoutPathExpansion(
588       shill::kStateProperty, shill::kStateIdle);
589   properties.SetStringWithoutPathExpansion(
590       shill::kProfileProperty, shill_stub_helper::kSharedProfilePath);
591
592   network_configuration_handler_->CreateConfiguration(
593       properties,
594       base::Bind(
595           &NetworkConfigurationHandlerStubTest::CreateConfigurationCallback,
596           base::Unretained(this)),
597       base::Bind(&ErrorCallback, false, service_path));
598   message_loop_.RunUntilIdle();
599
600   EXPECT_FALSE(create_service_path_.empty());
601
602   std::string guid;
603   EXPECT_TRUE(GetServiceStringProperty(
604       create_service_path_, shill::kGuidProperty, &guid));
605   EXPECT_EQ(service_path, guid);
606
607   std::string actual_profile;
608   EXPECT_TRUE(GetServiceStringProperty(
609       create_service_path_, shill::kProfileProperty, &actual_profile));
610   EXPECT_EQ(shill_stub_helper::kSharedProfilePath, actual_profile);
611 }
612
613 }  // namespace chromeos