Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chromeos / network / shill_property_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 "chromeos/network/shill_property_handler.h"
6
7 #include <map>
8 #include <set>
9 #include <string>
10
11 #include "base/bind.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/values.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/shill_device_client.h"
17 #include "chromeos/dbus/shill_ipconfig_client.h"
18 #include "chromeos/dbus/shill_manager_client.h"
19 #include "chromeos/dbus/shill_profile_client.h"
20 #include "chromeos/dbus/shill_service_client.h"
21 #include "dbus/object_path.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/cros_system_api/dbus/service_constants.h"
24
25 namespace chromeos {
26
27 namespace {
28
29 void DoNothingWithCallStatus(DBusMethodCallStatus call_status) {
30 }
31
32 void ErrorCallbackFunction(const std::string& error_name,
33                            const std::string& error_message) {
34   LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
35 }
36
37 class TestListener : public internal::ShillPropertyHandler::Listener {
38  public:
39   TestListener() : technology_list_updates_(0),
40                    errors_(0) {
41   }
42
43   virtual void UpdateManagedList(ManagedState::ManagedType type,
44                                  const base::ListValue& entries) override {
45     VLOG(1) << "UpdateManagedList[" << ManagedState::TypeToString(type) << "]: "
46             << entries.GetSize();
47     UpdateEntries(GetTypeString(type), entries);
48   }
49
50   virtual void UpdateManagedStateProperties(
51       ManagedState::ManagedType type,
52       const std::string& path,
53       const base::DictionaryValue& properties) override {
54     VLOG(2) << "UpdateManagedStateProperties: " << GetTypeString(type);
55     initial_property_updates(GetTypeString(type))[path] += 1;
56   }
57
58   virtual void ProfileListChanged() override {
59   }
60
61   virtual void UpdateNetworkServiceProperty(
62       const std::string& service_path,
63       const std::string& key,
64       const base::Value& value) override {
65     AddPropertyUpdate(shill::kServiceCompleteListProperty, service_path);
66   }
67
68   virtual void UpdateDeviceProperty(
69       const std::string& device_path,
70       const std::string& key,
71       const base::Value& value) override {
72     AddPropertyUpdate(shill::kDevicesProperty, device_path);
73   }
74
75   virtual void UpdateIPConfigProperties(
76       ManagedState::ManagedType type,
77       const std::string& path,
78       const std::string& ip_config_path,
79       const base::DictionaryValue& properties) override {
80     AddPropertyUpdate(shill::kIPConfigsProperty, ip_config_path);
81   }
82
83   virtual void TechnologyListChanged() override {
84     VLOG(1) << "TechnologyListChanged.";
85     ++technology_list_updates_;
86   }
87
88   virtual void CheckPortalListChanged(
89       const std::string& check_portal_list) override {
90   }
91
92   virtual void ManagedStateListChanged(
93       ManagedState::ManagedType type) override {
94     VLOG(1) << "ManagedStateListChanged: " << GetTypeString(type);
95     AddStateListUpdate(GetTypeString(type));
96   }
97
98   virtual void DefaultNetworkServiceChanged(
99       const std::string& service_path) override {
100   }
101
102   std::vector<std::string>& entries(const std::string& type) {
103     return entries_[type];
104   }
105   std::map<std::string, int>& property_updates(const std::string& type) {
106     return property_updates_[type];
107   }
108   std::map<std::string, int>& initial_property_updates(
109       const std::string& type) {
110     return initial_property_updates_[type];
111   }
112   int list_updates(const std::string& type) { return list_updates_[type]; }
113   int technology_list_updates() { return technology_list_updates_; }
114   void reset_list_updates() {
115     VLOG(1) << "=== RESET LIST UPDATES ===";
116     list_updates_.clear();
117     technology_list_updates_ = 0;
118   }
119   int errors() { return errors_; }
120
121  private:
122   std::string GetTypeString(ManagedState::ManagedType type) {
123     if (type == ManagedState::MANAGED_TYPE_NETWORK)
124       return shill::kServiceCompleteListProperty;
125     if (type == ManagedState::MANAGED_TYPE_DEVICE)
126       return shill::kDevicesProperty;
127     NOTREACHED();
128     return std::string();
129   }
130
131   void UpdateEntries(const std::string& type, const base::ListValue& entries) {
132     if (type.empty())
133       return;
134     entries_[type].clear();
135     for (base::ListValue::const_iterator iter = entries.begin();
136          iter != entries.end(); ++iter) {
137       std::string path;
138       if ((*iter)->GetAsString(&path))
139         entries_[type].push_back(path);
140     }
141   }
142
143   void AddPropertyUpdate(const std::string& type, const std::string& path) {
144     DCHECK(!type.empty());
145     VLOG(2) << "AddPropertyUpdate: " << type;
146     property_updates(type)[path] += 1;
147   }
148
149   void AddStateListUpdate(const std::string& type) {
150     DCHECK(!type.empty());
151     list_updates_[type] += 1;
152   }
153
154   // Map of list-type -> paths
155   std::map<std::string, std::vector<std::string> > entries_;
156   // Map of list-type -> map of paths -> update counts
157   std::map<std::string, std::map<std::string, int> > property_updates_;
158   std::map<std::string, std::map<std::string, int> > initial_property_updates_;
159   // Map of list-type -> list update counts
160   std::map<std::string, int > list_updates_;
161   int technology_list_updates_;
162   int errors_;
163 };
164
165 }  // namespace
166
167 class ShillPropertyHandlerTest : public testing::Test {
168  public:
169   ShillPropertyHandlerTest()
170       : manager_test_(NULL),
171         device_test_(NULL),
172         service_test_(NULL),
173         profile_test_(NULL) {
174   }
175   virtual ~ShillPropertyHandlerTest() {
176   }
177
178   virtual void SetUp() override {
179     // Initialize DBusThreadManager with a stub implementation.
180     DBusThreadManager::Initialize();
181     // Get the test interface for manager / device / service and clear the
182     // default stub properties.
183     manager_test_ =
184         DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
185     ASSERT_TRUE(manager_test_);
186     device_test_ =
187         DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
188     ASSERT_TRUE(device_test_);
189     service_test_ =
190         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
191     ASSERT_TRUE(service_test_);
192     profile_test_ =
193         DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
194     ASSERT_TRUE(profile_test_);
195     SetupShillPropertyHandler();
196     message_loop_.RunUntilIdle();
197   }
198
199   virtual void TearDown() override {
200     shill_property_handler_.reset();
201     listener_.reset();
202     DBusThreadManager::Shutdown();
203   }
204
205   void AddDevice(const std::string& type, const std::string& id) {
206     ASSERT_TRUE(IsValidType(type));
207     device_test_->AddDevice(id, type, id);
208   }
209
210   void RemoveDevice(const std::string& id) {
211     device_test_->RemoveDevice(id);
212   }
213
214   void AddService(const std::string& type,
215                   const std::string& id,
216                   const std::string& state) {
217     VLOG(2) << "AddService: " << type << ": " << id << ": " << state;
218     ASSERT_TRUE(IsValidType(type));
219     service_test_->AddService(id /* service_path */,
220                               id /* guid */,
221                               id /* name */,
222                               type,
223                               state,
224                               true /* visible */);
225   }
226
227   void AddServiceWithIPConfig(const std::string& type,
228                               const std::string& id,
229                               const std::string& state,
230                               const std::string& ipconfig_path) {
231     ASSERT_TRUE(IsValidType(type));
232     service_test_->AddServiceWithIPConfig(id, /* service_path */
233                                           id /* guid */,
234                                           id /* name */,
235                                           type,
236                                           state,
237                                           ipconfig_path,
238                                           true /* visible */);
239   }
240
241   void AddServiceToProfile(const std::string& type,
242                            const std::string& id,
243                            bool visible) {
244     service_test_->AddService(id /* service_path */,
245                               id /* guid */,
246                               id /* name */,
247                               type,
248                               shill::kStateIdle,
249                               visible);
250     std::vector<std::string> profiles;
251     profile_test_->GetProfilePaths(&profiles);
252     ASSERT_TRUE(profiles.size() > 0);
253     base::DictionaryValue properties;  // Empty entry
254     profile_test_->AddService(profiles[0], id);
255   }
256
257   void RemoveService(const std::string& id) {
258     service_test_->RemoveService(id);
259   }
260
261   // Call this after any initial Shill client setup
262   void SetupShillPropertyHandler() {
263     SetupDefaultShillState();
264     listener_.reset(new TestListener);
265     shill_property_handler_.reset(
266         new internal::ShillPropertyHandler(listener_.get()));
267     shill_property_handler_->Init();
268   }
269
270   bool IsValidType(const std::string& type) {
271     return (type == shill::kTypeEthernet ||
272             type == shill::kTypeEthernetEap ||
273             type == shill::kTypeWifi ||
274             type == shill::kTypeWimax ||
275             type == shill::kTypeBluetooth ||
276             type == shill::kTypeCellular ||
277             type == shill::kTypeVPN);
278   }
279
280  protected:
281   void SetupDefaultShillState() {
282     message_loop_.RunUntilIdle();  // Process any pending updates
283     device_test_->ClearDevices();
284     AddDevice(shill::kTypeWifi, "stub_wifi_device1");
285     AddDevice(shill::kTypeCellular, "stub_cellular_device1");
286     service_test_->ClearServices();
287     AddService(shill::kTypeEthernet, "stub_ethernet", shill::kStateOnline);
288     AddService(shill::kTypeWifi, "stub_wifi1", shill::kStateOnline);
289     AddService(shill::kTypeWifi, "stub_wifi2", shill::kStateIdle);
290     AddService(shill::kTypeCellular, "stub_cellular1", shill::kStateIdle);
291   }
292
293   base::MessageLoopForUI message_loop_;
294   scoped_ptr<TestListener> listener_;
295   scoped_ptr<internal::ShillPropertyHandler> shill_property_handler_;
296   ShillManagerClient::TestInterface* manager_test_;
297   ShillDeviceClient::TestInterface* device_test_;
298   ShillServiceClient::TestInterface* service_test_;
299   ShillProfileClient::TestInterface* profile_test_;
300
301  private:
302   DISALLOW_COPY_AND_ASSIGN(ShillPropertyHandlerTest);
303 };
304
305 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerStub) {
306   EXPECT_TRUE(shill_property_handler_->IsTechnologyAvailable(shill::kTypeWifi));
307   EXPECT_TRUE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi));
308   const size_t kNumShillManagerClientStubImplDevices = 2;
309   EXPECT_EQ(kNumShillManagerClientStubImplDevices,
310             listener_->entries(shill::kDevicesProperty).size());
311   const size_t kNumShillManagerClientStubImplServices = 4;
312   EXPECT_EQ(kNumShillManagerClientStubImplServices,
313             listener_->entries(shill::kServiceCompleteListProperty).size());
314
315   EXPECT_EQ(0, listener_->errors());
316 }
317
318 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerTechnologyChanged) {
319   const int initial_technology_updates = 2;  // Available and Enabled lists
320   EXPECT_EQ(initial_technology_updates, listener_->technology_list_updates());
321
322   // Remove an enabled technology. Updates both the Available and Enabled lists.
323   listener_->reset_list_updates();
324   manager_test_->RemoveTechnology(shill::kTypeWifi);
325   message_loop_.RunUntilIdle();
326   EXPECT_EQ(2, listener_->technology_list_updates());
327
328   // Add a disabled technology.
329   listener_->reset_list_updates();
330   manager_test_->AddTechnology(shill::kTypeWifi, false);
331   message_loop_.RunUntilIdle();
332   EXPECT_EQ(1, listener_->technology_list_updates());
333   EXPECT_TRUE(shill_property_handler_->IsTechnologyAvailable(
334       shill::kTypeWifi));
335   EXPECT_FALSE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi));
336
337   // Enable the technology.
338   listener_->reset_list_updates();
339   DBusThreadManager::Get()->GetShillManagerClient()->EnableTechnology(
340       shill::kTypeWifi,
341       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
342   message_loop_.RunUntilIdle();
343   EXPECT_EQ(1, listener_->technology_list_updates());
344   EXPECT_TRUE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi));
345
346   EXPECT_EQ(0, listener_->errors());
347 }
348
349 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerDevicePropertyChanged) {
350   const size_t kNumShillManagerClientStubImplDevices = 2;
351   EXPECT_EQ(kNumShillManagerClientStubImplDevices,
352             listener_->entries(shill::kDevicesProperty).size());
353   // Add a device.
354   listener_->reset_list_updates();
355   const std::string kTestDevicePath("test_wifi_device1");
356   AddDevice(shill::kTypeWifi, kTestDevicePath);
357   message_loop_.RunUntilIdle();
358   EXPECT_EQ(1, listener_->list_updates(shill::kDevicesProperty));
359   EXPECT_EQ(kNumShillManagerClientStubImplDevices + 1,
360             listener_->entries(shill::kDevicesProperty).size());
361
362   // Remove a device
363   listener_->reset_list_updates();
364   RemoveDevice(kTestDevicePath);
365   message_loop_.RunUntilIdle();
366   EXPECT_EQ(1, listener_->list_updates(shill::kDevicesProperty));
367   EXPECT_EQ(kNumShillManagerClientStubImplDevices,
368             listener_->entries(shill::kDevicesProperty).size());
369
370   EXPECT_EQ(0, listener_->errors());
371 }
372
373 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServicePropertyChanged) {
374   const size_t kNumShillManagerClientStubImplServices = 4;
375   EXPECT_EQ(kNumShillManagerClientStubImplServices,
376             listener_->entries(shill::kServiceCompleteListProperty).size());
377
378   // Add a service.
379   listener_->reset_list_updates();
380   const std::string kTestServicePath("test_wifi_service1");
381   AddService(shill::kTypeWifi, kTestServicePath, shill::kStateIdle);
382   message_loop_.RunUntilIdle();
383   // Add should trigger a service list update and update entries.
384   EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
385   EXPECT_EQ(kNumShillManagerClientStubImplServices + 1,
386             listener_->entries(shill::kServiceCompleteListProperty).size());
387   // Service receives an initial property update.
388   EXPECT_EQ(1, listener_->initial_property_updates(
389       shill::kServiceCompleteListProperty)[kTestServicePath]);
390   // Change a property.
391   base::FundamentalValue scan_interval(3);
392   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
393       dbus::ObjectPath(kTestServicePath),
394       shill::kScanIntervalProperty,
395       scan_interval,
396       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
397   message_loop_.RunUntilIdle();
398   // Property change triggers an update (but not a service list update).
399   EXPECT_EQ(1, listener_->property_updates(
400       shill::kServiceCompleteListProperty)[kTestServicePath]);
401
402   // Change the visibility of a service. This will trigger a service list
403   // updates.
404   listener_->reset_list_updates();
405   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
406       dbus::ObjectPath(kTestServicePath),
407       shill::kVisibleProperty,
408       base::FundamentalValue(false),
409       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
410   message_loop_.RunUntilIdle();
411   EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
412
413   // Remove a service. This will update the entries and signal a service list
414   // update.
415   listener_->reset_list_updates();
416   RemoveService(kTestServicePath);
417   message_loop_.RunUntilIdle();
418   EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
419   EXPECT_EQ(kNumShillManagerClientStubImplServices,
420             listener_->entries(shill::kServiceCompleteListProperty).size());
421
422   EXPECT_EQ(0, listener_->errors());
423 }
424
425 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerIPConfigPropertyChanged) {
426   // Set the properties for an IP Config object.
427   const std::string kTestIPConfigPath("test_ip_config_path");
428
429   base::StringValue ip_address("192.168.1.1");
430   DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
431       dbus::ObjectPath(kTestIPConfigPath),
432       shill::kAddressProperty, ip_address,
433       base::Bind(&DoNothingWithCallStatus));
434   base::ListValue dns_servers;
435   dns_servers.Append(new base::StringValue("192.168.1.100"));
436   dns_servers.Append(new base::StringValue("192.168.1.101"));
437   DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
438       dbus::ObjectPath(kTestIPConfigPath),
439       shill::kNameServersProperty, dns_servers,
440       base::Bind(&DoNothingWithCallStatus));
441   base::FundamentalValue prefixlen(8);
442   DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
443       dbus::ObjectPath(kTestIPConfigPath),
444       shill::kPrefixlenProperty, prefixlen,
445       base::Bind(&DoNothingWithCallStatus));
446   base::StringValue gateway("192.0.0.1");
447   DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
448       dbus::ObjectPath(kTestIPConfigPath),
449       shill::kGatewayProperty, gateway,
450       base::Bind(&DoNothingWithCallStatus));
451   message_loop_.RunUntilIdle();
452
453   // Add a service with an empty ipconfig and then update
454   // its ipconfig property.
455   const std::string kTestServicePath1("test_wifi_service1");
456   AddService(shill::kTypeWifi, kTestServicePath1, shill::kStateIdle);
457   message_loop_.RunUntilIdle();
458   // This is the initial property update.
459   EXPECT_EQ(1, listener_->initial_property_updates(
460       shill::kServiceCompleteListProperty)[kTestServicePath1]);
461   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
462       dbus::ObjectPath(kTestServicePath1),
463       shill::kIPConfigProperty,
464       base::StringValue(kTestIPConfigPath),
465       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
466   message_loop_.RunUntilIdle();
467   // IPConfig property change on the service should trigger an IPConfigs update.
468   EXPECT_EQ(1, listener_->property_updates(
469       shill::kIPConfigsProperty)[kTestIPConfigPath]);
470
471   // Now, Add a new service with the IPConfig already set.
472   const std::string kTestServicePath2("test_wifi_service2");
473   AddServiceWithIPConfig(shill::kTypeWifi, kTestServicePath2,
474                          shill::kStateIdle, kTestIPConfigPath);
475   message_loop_.RunUntilIdle();
476   // A service with the IPConfig property already set should trigger an
477   // additional IPConfigs update.
478   EXPECT_EQ(2, listener_->property_updates(
479       shill::kIPConfigsProperty)[kTestIPConfigPath]);
480 }
481
482 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServiceList) {
483   // Add an entry to the profile only.
484   const std::string kTestServicePath1("stub_wifi_profile_only1");
485   AddServiceToProfile(shill::kTypeWifi, kTestServicePath1, false /* visible */);
486   message_loop_.RunUntilIdle();
487
488   // Update the Manager properties. This should trigger a single list update,
489   // an initial property update, and a regular property update.
490   listener_->reset_list_updates();
491   shill_property_handler_->UpdateManagerProperties();
492   message_loop_.RunUntilIdle();
493   EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
494   EXPECT_EQ(1, listener_->initial_property_updates(
495       shill::kServiceCompleteListProperty)[kTestServicePath1]);
496   EXPECT_EQ(1, listener_->property_updates(
497       shill::kServiceCompleteListProperty)[kTestServicePath1]);
498
499   // Add a new entry to the services and the profile; should also trigger a
500   // service list update, and a property update.
501   listener_->reset_list_updates();
502   const std::string kTestServicePath2("stub_wifi_profile_only2");
503   AddServiceToProfile(shill::kTypeWifi, kTestServicePath2, true);
504   shill_property_handler_->UpdateManagerProperties();
505   message_loop_.RunUntilIdle();
506   EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
507   EXPECT_EQ(1, listener_->initial_property_updates(
508       shill::kServiceCompleteListProperty)[kTestServicePath2]);
509   EXPECT_EQ(1, listener_->property_updates(
510       shill::kServiceCompleteListProperty)[kTestServicePath2]);
511 }
512
513 }  // namespace chromeos