1 //
2 // Copyright (C) 2012 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 //
16 
17 #include "shill/default_profile.h"
18 
19 #include <map>
20 #include <memory>
21 #include <set>
22 #include <string>
23 #include <vector>
24 
25 #include <base/files/file_path.h>
26 #if defined(__ANDROID__)
27 #include <dbus/service_constants.h>
28 #else
29 #include <chromeos/dbus/service_constants.h>
30 #endif  // __ANDROID__
31 #include <gtest/gtest.h>
32 #include <gmock/gmock.h>
33 
34 #include "shill/connectivity_trial.h"
35 #include "shill/link_monitor.h"
36 #include "shill/manager.h"
37 #include "shill/mock_control.h"
38 #include "shill/mock_device.h"
39 #include "shill/mock_dhcp_properties.h"
40 #include "shill/mock_service.h"
41 #include "shill/mock_store.h"
42 #include "shill/portal_detector.h"
43 #include "shill/property_store_unittest.h"
44 #include "shill/resolver.h"
45 
46 #if !defined(DISABLE_WIFI)
47 #include "shill/wifi/mock_wifi_provider.h"
48 #include "shill/wifi/wifi_service.h"
49 #endif  // DISABLE_WIFI
50 
51 using base::FilePath;
52 using std::map;
53 using std::set;
54 using std::string;
55 using std::unique_ptr;
56 using std::vector;
57 using ::testing::_;
58 using ::testing::DoAll;
59 using ::testing::NiceMock;
60 using ::testing::Return;
61 using ::testing::SetArgumentPointee;
62 
63 namespace shill {
64 
65 class DefaultProfileTest : public PropertyStoreTest {
66  public:
DefaultProfileTest()67   DefaultProfileTest()
68       : profile_(new DefaultProfile(control_interface(),
69                                     metrics(),
70                                     manager(),
71                                     FilePath(storage_path()),
72                                     DefaultProfile::kDefaultId,
73                                     properties_)),
74         device_(new MockDevice(control_interface(),
75                                dispatcher(),
76                                metrics(),
77                                manager(),
78                                "null0",
79                                "addr0",
80                                0)) {
81   }
82 
~DefaultProfileTest()83   virtual ~DefaultProfileTest() {}
84 
85  protected:
86   static const char kTestStoragePath[];
87 
88   scoped_refptr<DefaultProfile> profile_;
89   scoped_refptr<MockDevice> device_;
90   Manager::Properties properties_;
91 };
92 
93 const char DefaultProfileTest::kTestStoragePath[] = "/no/where";
94 
TEST_F(DefaultProfileTest,GetProperties)95 TEST_F(DefaultProfileTest, GetProperties) {
96   // DBusAdaptor::GetProperties() will iterate over all the accessors
97   // provided by Profile. The |kEntriesProperty| accessor calls
98   // GetGroups() on the StoreInterface.
99   unique_ptr<MockStore> storage(new MockStore());
100   set<string> empty_group_set;
101   EXPECT_CALL(*storage.get(), GetGroups())
102       .WillRepeatedly(Return(empty_group_set));
103   profile_->set_storage(storage.release());
104 
105   Error error(Error::kInvalidProperty, "");
106   {
107     brillo::VariantDictionary props;
108     Error error;
109     profile_->store().GetProperties(&props, &error);
110     ASSERT_FALSE(props.find(kOfflineModeProperty) == props.end());
111     EXPECT_TRUE(props[kOfflineModeProperty].IsTypeCompatible<bool>());
112     EXPECT_FALSE(props[kOfflineModeProperty].Get<bool>());
113   }
114   properties_.offline_mode = true;
115   {
116     brillo::VariantDictionary props;
117     Error error;
118     profile_->store().GetProperties(&props, &error);
119     ASSERT_FALSE(props.find(kOfflineModeProperty) == props.end());
120     EXPECT_TRUE(props[kOfflineModeProperty].IsTypeCompatible<bool>());
121     EXPECT_TRUE(props[kOfflineModeProperty].Get<bool>());
122   }
123   {
124     Error error(Error::kInvalidProperty, "");
125     EXPECT_FALSE(
126         profile_->mutable_store()->SetBoolProperty(
127             kOfflineModeProperty,
128             true,
129             &error));
130   }
131 }
132 
TEST_F(DefaultProfileTest,Save)133 TEST_F(DefaultProfileTest, Save) {
134   unique_ptr<MockStore> storage(new MockStore());
135   EXPECT_CALL(*storage.get(), SetBool(DefaultProfile::kStorageId,
136                                       DefaultProfile::kStorageArpGateway,
137                                       true))
138       .WillOnce(Return(true));
139   EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId,
140                                         DefaultProfile::kStorageName,
141                                         DefaultProfile::kDefaultId))
142       .WillOnce(Return(true));
143   EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId,
144                                         DefaultProfile::kStorageHostName,
145                                         ""))
146       .WillOnce(Return(true));
147   EXPECT_CALL(*storage.get(), SetBool(DefaultProfile::kStorageId,
148                                       DefaultProfile::kStorageOfflineMode,
149                                       false))
150       .WillOnce(Return(true));
151   EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId,
152                                         DefaultProfile::kStorageCheckPortalList,
153                                         ""))
154       .WillOnce(Return(true));
155   EXPECT_CALL(*storage.get(),
156               SetString(DefaultProfile::kStorageId,
157                         DefaultProfile::kStorageIgnoredDNSSearchPaths,
158                         ""))
159       .WillOnce(Return(true));
160   EXPECT_CALL(*storage.get(),
161               SetString(DefaultProfile::kStorageId,
162                         DefaultProfile::kStorageLinkMonitorTechnologies,
163                         ""))
164       .WillOnce(Return(true));
165   EXPECT_CALL(*storage.get(),
166               SetString(DefaultProfile::kStorageId,
167                         DefaultProfile::kStorageNoAutoConnectTechnologies,
168                         ""))
169       .WillOnce(Return(true));
170   EXPECT_CALL(*storage.get(),
171               SetString(DefaultProfile::kStorageId,
172                         DefaultProfile::kStorageProhibitedTechnologies,
173                         ""))
174       .WillOnce(Return(true));
175   EXPECT_CALL(*storage.get(), SetString(DefaultProfile::kStorageId,
176                                         DefaultProfile::kStoragePortalURL,
177                                         ""))
178       .WillOnce(Return(true));
179   EXPECT_CALL(*storage.get(),
180               SetString(DefaultProfile::kStorageId,
181                         DefaultProfile::kStoragePortalCheckInterval,
182                         "0"))
183       .WillOnce(Return(true));
184   EXPECT_CALL(*storage.get(), Flush()).WillOnce(Return(true));
185 
186   EXPECT_CALL(*device_.get(), Save(storage.get())).Times(0);
187   profile_->set_storage(storage.release());
188   unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties());
189   EXPECT_CALL(*dhcp_props.get(), Save(_,_));
190   manager()->dhcp_properties_ = std::move(dhcp_props);
191 
192   manager()->RegisterDevice(device_);
193   ASSERT_TRUE(profile_->Save());
194   manager()->DeregisterDevice(device_);
195 }
196 
TEST_F(DefaultProfileTest,LoadManagerDefaultProperties)197 TEST_F(DefaultProfileTest, LoadManagerDefaultProperties) {
198   unique_ptr<MockStore> storage(new MockStore());
199   Manager::Properties manager_props;
200   EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId,
201                                       DefaultProfile::kStorageArpGateway,
202                                       &manager_props.arp_gateway))
203       .WillOnce(Return(false));
204   EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
205                                         DefaultProfile::kStorageHostName,
206                                         &manager_props.host_name))
207       .WillOnce(Return(false));
208   EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId,
209                                       DefaultProfile::kStorageOfflineMode,
210                                       &manager_props.offline_mode))
211       .WillOnce(Return(false));
212   EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
213                                         DefaultProfile::kStorageCheckPortalList,
214                                         &manager_props.check_portal_list))
215       .WillOnce(Return(false));
216   EXPECT_CALL(*storage.get(),
217               GetString(DefaultProfile::kStorageId,
218                         DefaultProfile::kStorageIgnoredDNSSearchPaths,
219                         &manager_props.ignored_dns_search_paths))
220       .WillOnce(Return(false));
221   EXPECT_CALL(*storage.get(),
222               GetString(DefaultProfile::kStorageId,
223                         DefaultProfile::kStorageLinkMonitorTechnologies,
224                         _))
225       .WillOnce(Return(false));
226   EXPECT_CALL(*storage.get(),
227               GetString(DefaultProfile::kStorageId,
228                         DefaultProfile::kStorageNoAutoConnectTechnologies,
229                         _))
230       .WillOnce(Return(false));
231   EXPECT_CALL(*storage.get(),
232               GetString(DefaultProfile::kStorageId,
233                         DefaultProfile::kStorageProhibitedTechnologies,
234                         _))
235       .WillOnce(Return(false));
236   EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
237                                         DefaultProfile::kStoragePortalURL,
238                                         &manager_props.portal_url))
239       .WillOnce(Return(false));
240   EXPECT_CALL(*storage.get(),
241               GetString(DefaultProfile::kStorageId,
242                         DefaultProfile::kStoragePortalCheckInterval,
243                         _))
244       .WillOnce(Return(false));
245   unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties());
246   EXPECT_CALL(*dhcp_props.get(), Load(_, DefaultProfile::kStorageId));
247   manager()->dhcp_properties_ = std::move(dhcp_props);
248   profile_->set_storage(storage.release());
249 
250   profile_->LoadManagerProperties(&manager_props,
251                                   manager()->dhcp_properties_.get());
252   EXPECT_TRUE(manager_props.arp_gateway);
253   EXPECT_EQ("", manager_props.host_name);
254   EXPECT_FALSE(manager_props.offline_mode);
255   EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
256             manager_props.check_portal_list);
257   EXPECT_EQ(Resolver::kDefaultIgnoredSearchList,
258             manager_props.ignored_dns_search_paths);
259   EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies,
260             manager_props.link_monitor_technologies);
261   EXPECT_EQ("", manager_props.no_auto_connect_technologies);
262   EXPECT_EQ(ConnectivityTrial::kDefaultURL, manager_props.portal_url);
263   EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds,
264             manager_props.portal_check_interval_seconds);
265   EXPECT_EQ("", manager_props.prohibited_technologies);
266 }
267 
TEST_F(DefaultProfileTest,LoadManagerProperties)268 TEST_F(DefaultProfileTest, LoadManagerProperties) {
269   unique_ptr<MockStore> storage(new MockStore());
270   const string host_name("hostname");
271   EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId,
272                                       DefaultProfile::kStorageArpGateway,
273                                       _))
274       .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)));
275   EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
276                                         DefaultProfile::kStorageHostName,
277                                         _))
278       .WillOnce(DoAll(SetArgumentPointee<2>(host_name), Return(true)));
279   EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId,
280                                       DefaultProfile::kStorageOfflineMode,
281                                       _))
282       .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
283   const string portal_list("technology1,technology2");
284   EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
285                                         DefaultProfile::kStorageCheckPortalList,
286                                         _))
287       .WillOnce(DoAll(SetArgumentPointee<2>(portal_list), Return(true)));
288   const string ignored_paths("chromium.org,google.com");
289   EXPECT_CALL(*storage.get(),
290               GetString(DefaultProfile::kStorageId,
291                         DefaultProfile::kStorageIgnoredDNSSearchPaths,
292                         _))
293       .WillOnce(DoAll(SetArgumentPointee<2>(ignored_paths), Return(true)));
294   const string link_monitor_technologies("ethernet,wimax");
295   EXPECT_CALL(*storage.get(),
296               GetString(DefaultProfile::kStorageId,
297                         DefaultProfile::kStorageLinkMonitorTechnologies,
298                         _))
299       .WillOnce(DoAll(SetArgumentPointee<2>(link_monitor_technologies),
300                       Return(true)));
301   const string no_auto_connect_technologies("wifi,cellular");
302   EXPECT_CALL(*storage.get(),
303               GetString(DefaultProfile::kStorageId,
304                         DefaultProfile::kStorageNoAutoConnectTechnologies,
305                         _))
306       .WillOnce(DoAll(SetArgumentPointee<2>(no_auto_connect_technologies),
307                       Return(true)));
308   const string portal_url("http://www.chromium.org");
309   EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
310                                         DefaultProfile::kStoragePortalURL,
311                                         _))
312       .WillOnce(DoAll(SetArgumentPointee<2>(portal_url), Return(true)));
313   const string portal_check_interval_string("10");
314   const int portal_check_interval_int = 10;
315   EXPECT_CALL(*storage.get(),
316               GetString(DefaultProfile::kStorageId,
317                         DefaultProfile::kStoragePortalCheckInterval,
318                         _))
319       .WillOnce(DoAll(SetArgumentPointee<2>(portal_check_interval_string),
320                       Return(true)));
321   const string prohibited_technologies("vpn,wimax");
322   EXPECT_CALL(*storage.get(),
323               GetString(DefaultProfile::kStorageId,
324                         DefaultProfile::kStorageProhibitedTechnologies,
325                         _))
326       .WillOnce(DoAll(SetArgumentPointee<2>(prohibited_technologies),
327                       Return(true)));
328   profile_->set_storage(storage.release());
329   Manager::Properties manager_props;
330   unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties());
331   EXPECT_CALL(*dhcp_props.get(), Load(_, DefaultProfile::kStorageId));
332   manager()->dhcp_properties_ = std::move(dhcp_props);
333 
334   profile_->LoadManagerProperties(&manager_props,
335                                   manager()->dhcp_properties_.get());
336   EXPECT_FALSE(manager_props.arp_gateway);
337   EXPECT_EQ(host_name, manager_props.host_name);
338   EXPECT_TRUE(manager_props.offline_mode);
339   EXPECT_EQ(portal_list, manager_props.check_portal_list);
340   EXPECT_EQ(ignored_paths, manager_props.ignored_dns_search_paths);
341   EXPECT_EQ(link_monitor_technologies,
342             manager_props.link_monitor_technologies);
343   EXPECT_EQ(no_auto_connect_technologies,
344             manager_props.no_auto_connect_technologies);
345   EXPECT_EQ(portal_url, manager_props.portal_url);
346   EXPECT_EQ(portal_check_interval_int,
347             manager_props.portal_check_interval_seconds);
348   EXPECT_EQ(prohibited_technologies, manager_props.prohibited_technologies);
349 }
350 
TEST_F(DefaultProfileTest,GetStoragePath)351 TEST_F(DefaultProfileTest, GetStoragePath) {
352 #if defined(ENABLE_JSON_STORE)
353   EXPECT_EQ(storage_path() + "/default.profile.json",
354             profile_->persistent_profile_path().value());
355 #else
356   EXPECT_EQ(storage_path() + "/default.profile",
357             profile_->persistent_profile_path().value());
358 #endif
359 }
360 
TEST_F(DefaultProfileTest,ConfigureService)361 TEST_F(DefaultProfileTest, ConfigureService) {
362   unique_ptr<MockStore> storage(new MockStore());
363   EXPECT_CALL(*storage, ContainsGroup(_))
364       .WillRepeatedly(Return(false));
365   EXPECT_CALL(*storage, Flush())
366       .WillOnce(Return(true));
367 
368   scoped_refptr<MockService> unknown_service(new MockService(
369       control_interface(),
370       dispatcher(),
371       metrics(),
372       manager()));
373   EXPECT_CALL(*unknown_service, technology())
374       .WillOnce(Return(Technology::kUnknown));
375   EXPECT_CALL(*unknown_service, Save(_)) .Times(0);
376 
377   scoped_refptr<MockService> ethernet_service(new MockService(
378       control_interface(),
379       dispatcher(),
380       metrics(),
381       manager()));
382   EXPECT_CALL(*ethernet_service, technology())
383       .WillOnce(Return(Technology::kEthernet));
384   EXPECT_CALL(*ethernet_service, Save(storage.get()))
385       .WillOnce(Return(true));
386 
387   profile_->set_storage(storage.release());
388   EXPECT_FALSE(profile_->ConfigureService(unknown_service));
389   EXPECT_TRUE(profile_->ConfigureService(ethernet_service));
390 }
391 
TEST_F(DefaultProfileTest,UpdateDevice)392 TEST_F(DefaultProfileTest, UpdateDevice) {
393   unique_ptr<MockStore> storage(new MockStore());
394   EXPECT_CALL(*storage, Flush()).WillOnce(Return(true));
395   EXPECT_CALL(*device_, Save(storage.get()))
396       .WillOnce(Return(true))
397       .WillOnce(Return(false));
398   profile_->set_storage(storage.release());
399   EXPECT_TRUE(profile_->UpdateDevice(device_));
400   EXPECT_FALSE(profile_->UpdateDevice(device_));
401 }
402 
403 #if !defined(DISABLE_WIFI)
TEST_F(DefaultProfileTest,UpdateWiFiProvider)404 TEST_F(DefaultProfileTest, UpdateWiFiProvider) {
405   MockWiFiProvider wifi_provider;
406 
407   {
408     unique_ptr<MockStore> storage(new MockStore());
409     EXPECT_CALL(*storage, Flush()).Times(0);
410     EXPECT_CALL(wifi_provider, Save(storage.get())).WillOnce(Return(false));
411     profile_->set_storage(storage.release());
412     EXPECT_FALSE(profile_->UpdateWiFiProvider(wifi_provider));
413   }
414 
415   {
416     unique_ptr<MockStore> storage(new MockStore());
417     EXPECT_CALL(*storage, Flush()).WillOnce(Return(false));
418     EXPECT_CALL(wifi_provider, Save(storage.get())).WillOnce(Return(true));
419     profile_->set_storage(storage.release());
420     EXPECT_FALSE(profile_->UpdateWiFiProvider(wifi_provider));
421   }
422 
423   {
424     unique_ptr<MockStore> storage(new MockStore());
425     EXPECT_CALL(*storage, Flush()).WillOnce(Return(true));
426     EXPECT_CALL(wifi_provider, Save(storage.get())).WillOnce(Return(true));
427     profile_->set_storage(storage.release());
428     EXPECT_TRUE(profile_->UpdateWiFiProvider(wifi_provider));
429   }
430 }
431 #endif  // DISABLE_WIFI
432 
433 }  // namespace shill
434