• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2014 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 #include "update_engine/update_manager/real_shill_provider.h"
17 
18 #include <memory>
19 #include <utility>
20 
21 #include <base/time/time.h>
22 #include <brillo/make_unique_ptr.h>
23 #include <brillo/message_loops/fake_message_loop.h>
24 #include <gmock/gmock.h>
25 #include <gtest/gtest.h>
26 #include <shill/dbus-constants.h>
27 #include <shill/dbus-proxies.h>
28 #include <shill/dbus-proxy-mocks.h>
29 
30 #include "update_engine/common/fake_clock.h"
31 #include "update_engine/common/test_utils.h"
32 #include "update_engine/dbus_test_utils.h"
33 #include "update_engine/fake_shill_proxy.h"
34 #include "update_engine/update_manager/umtest_utils.h"
35 
36 using base::Time;
37 using base::TimeDelta;
38 using chromeos_update_engine::ConnectionTethering;
39 using chromeos_update_engine::ConnectionType;
40 using chromeos_update_engine::FakeClock;
41 using org::chromium::flimflam::ManagerProxyMock;
42 using org::chromium::flimflam::ServiceProxyMock;
43 using std::unique_ptr;
44 using testing::Mock;
45 using testing::Return;
46 using testing::SetArgPointee;
47 using testing::_;
48 
49 namespace {
50 
51 // Fake service paths.
52 const char* const kFakeEthernetServicePath = "/fake/ethernet/service";
53 const char* const kFakeWifiServicePath = "/fake/wifi/service";
54 const char* const kFakeWimaxServicePath = "/fake/wimax/service";
55 const char* const kFakeBluetoothServicePath = "/fake/bluetooth/service";
56 const char* const kFakeCellularServicePath = "/fake/cellular/service";
57 const char* const kFakeVpnServicePath = "/fake/vpn/service";
58 const char* const kFakeUnknownServicePath = "/fake/unknown/service";
59 
60 }  // namespace
61 
62 namespace chromeos_update_manager {
63 
64 class UmRealShillProviderTest : public ::testing::Test {
65  protected:
66   // Initialize the RealShillProvider under test.
SetUp()67   void SetUp() override {
68     fake_clock_.SetWallclockTime(InitTime());
69     loop_.SetAsCurrent();
70     fake_shill_proxy_ = new chromeos_update_engine::FakeShillProxy();
71     provider_.reset(new RealShillProvider(fake_shill_proxy_, &fake_clock_));
72 
73     ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_->GetManagerProxy();
74 
75     // The PropertyChanged signal should be subscribed to.
76     MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(
77         manager_property_changed_, *manager_proxy_mock, PropertyChanged);
78   }
79 
TearDown()80   void TearDown() override {
81     provider_.reset();
82     // Check for leaked callbacks on the main loop.
83     EXPECT_FALSE(loop_.PendingTasks());
84   }
85 
86   // These methods generate fixed timestamps for use in faking the current time.
InitTime()87   Time InitTime() {
88     Time::Exploded now_exp;
89     now_exp.year = 2014;
90     now_exp.month = 3;
91     now_exp.day_of_week = 2;
92     now_exp.day_of_month = 18;
93     now_exp.hour = 8;
94     now_exp.minute = 5;
95     now_exp.second = 33;
96     now_exp.millisecond = 675;
97     return Time::FromLocalExploded(now_exp);
98   }
99 
ConnChangedTime()100   Time ConnChangedTime() {
101     return InitTime() + TimeDelta::FromSeconds(10);
102   }
103 
104   // Sets the default_service object path in the response from the
105   // ManagerProxyMock instance.
106   void SetManagerReply(const char* default_service, bool reply_succeeds);
107 
108   // Sets the |service_type|, |physical_technology| and |service_tethering|
109   // properties in the mocked service |service_path|. If any of the three
110   // const char* is a nullptr, the corresponding property will not be included
111   // in the response.
112   // Returns the mock object pointer, owned by the |fake_shill_proxy_|.
113   ServiceProxyMock* SetServiceReply(const std::string& service_path,
114                                     const char* service_type,
115                                     const char* physical_technology,
116                                     const char* service_tethering);
117 
InitWithDefaultService(const char * default_service)118   void InitWithDefaultService(const char* default_service) {
119     SetManagerReply(default_service, true);
120     // Check that provider initializes correctly.
121     EXPECT_TRUE(provider_->Init());
122     // RunOnce to notify the signal handler was connected properly.
123     EXPECT_TRUE(loop_.RunOnce(false));
124   }
125 
126   // Sends a signal informing the provider about a default connection
127   // |service_path|. Sets the fake connection change time in
128   // |conn_change_time_p| if provided.
SendDefaultServiceSignal(const std::string & service_path,Time * conn_change_time_p)129   void SendDefaultServiceSignal(const std::string& service_path,
130                                 Time* conn_change_time_p) {
131     const Time conn_change_time = ConnChangedTime();
132     fake_clock_.SetWallclockTime(conn_change_time);
133     ASSERT_TRUE(manager_property_changed_.IsHandlerRegistered());
134     manager_property_changed_.signal_callback().Run(
135         shill::kDefaultServiceProperty, dbus::ObjectPath(service_path));
136     fake_clock_.SetWallclockTime(conn_change_time + TimeDelta::FromSeconds(5));
137     if (conn_change_time_p)
138       *conn_change_time_p = conn_change_time;
139   }
140 
141   // Sets up expectations for detection of a connection |service_path| with type
142   // |shill_type_str| and tethering mode |shill_tethering_str|. Ensures that the
143   // new connection status and change time are properly detected by the
144   // provider. Writes the fake connection change time to |conn_change_time_p|,
145   // if provided.
SetupConnectionAndAttrs(const std::string & service_path,const char * shill_type,const char * shill_tethering,Time * conn_change_time_p)146   void SetupConnectionAndAttrs(const std::string& service_path,
147                                const char* shill_type,
148                                const char* shill_tethering,
149                                Time* conn_change_time_p) {
150     SetServiceReply(service_path, shill_type, nullptr, shill_tethering);
151     // Note: We don't setup this |service_path| as the default service path but
152     // we instead send a signal notifying the change since the code won't call
153     // GetProperties on the Manager object at this point.
154 
155     // Send a signal about a new default service.
156     Time conn_change_time;
157     SendDefaultServiceSignal(service_path, &conn_change_time);
158 
159     // Query the connection status, ensure last change time reported correctly.
160     UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_connected());
161     UmTestUtils::ExpectVariableHasValue(conn_change_time,
162                                         provider_->var_conn_last_changed());
163 
164     // Write the connection change time to the output argument.
165     if (conn_change_time_p)
166       *conn_change_time_p = conn_change_time;
167   }
168 
169   // Sets up a connection and tests that its type is being properly detected by
170   // the provider.
SetupConnectionAndTestType(const char * service_path,const char * shill_type,ConnectionType expected_conn_type)171   void SetupConnectionAndTestType(const char* service_path,
172                                   const char* shill_type,
173                                   ConnectionType expected_conn_type) {
174     // Set up and test the connection, record the change time.
175     Time conn_change_time;
176     SetupConnectionAndAttrs(service_path,
177                             shill_type,
178                             shill::kTetheringNotDetectedState,
179                             &conn_change_time);
180 
181     // Query the connection type, ensure last change time did not change.
182     UmTestUtils::ExpectVariableHasValue(expected_conn_type,
183                                         provider_->var_conn_type());
184     UmTestUtils::ExpectVariableHasValue(conn_change_time,
185                                         provider_->var_conn_last_changed());
186   }
187 
188   // Sets up a connection and tests that its tethering mode is being properly
189   // detected by the provider.
SetupConnectionAndTestTethering(const char * service_path,const char * shill_tethering,ConnectionTethering expected_conn_tethering)190   void SetupConnectionAndTestTethering(
191       const char* service_path,
192       const char* shill_tethering,
193       ConnectionTethering expected_conn_tethering) {
194     // Set up and test the connection, record the change time.
195     Time conn_change_time;
196     SetupConnectionAndAttrs(
197         service_path, shill::kTypeEthernet, shill_tethering, &conn_change_time);
198 
199     // Query the connection tethering, ensure last change time did not change.
200     UmTestUtils::ExpectVariableHasValue(expected_conn_tethering,
201                                         provider_->var_conn_tethering());
202     UmTestUtils::ExpectVariableHasValue(conn_change_time,
203                                         provider_->var_conn_last_changed());
204   }
205 
206   brillo::FakeMessageLoop loop_{nullptr};
207   FakeClock fake_clock_;
208   chromeos_update_engine::FakeShillProxy* fake_shill_proxy_;
209 
210   // The registered signal handler for the signal Manager.PropertyChanged.
211   chromeos_update_engine::dbus_test_utils::MockSignalHandler<
212       void(const std::string&, const brillo::Any&)> manager_property_changed_;
213 
214   unique_ptr<RealShillProvider> provider_;
215 };
216 
SetManagerReply(const char * default_service,bool reply_succeeds)217 void UmRealShillProviderTest::SetManagerReply(const char* default_service,
218                                               bool reply_succeeds) {
219   ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_->GetManagerProxy();
220   if (!reply_succeeds) {
221     EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
222         .WillOnce(Return(false));
223     return;
224   }
225 
226   // Create a dictionary of properties and optionally include the default
227   // service.
228   brillo::VariantDictionary reply_dict;
229   reply_dict["SomeOtherProperty"] = 0xC0FFEE;
230 
231   if (default_service) {
232     reply_dict[shill::kDefaultServiceProperty] =
233         dbus::ObjectPath(default_service);
234   }
235   EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
236       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
237 }
238 
SetServiceReply(const std::string & service_path,const char * service_type,const char * physical_technology,const char * service_tethering)239 ServiceProxyMock* UmRealShillProviderTest::SetServiceReply(
240     const std::string& service_path,
241     const char* service_type,
242     const char* physical_technology,
243     const char* service_tethering) {
244   brillo::VariantDictionary reply_dict;
245   reply_dict["SomeOtherProperty"] = 0xC0FFEE;
246 
247   if (service_type)
248     reply_dict[shill::kTypeProperty] = std::string(service_type);
249 
250   if (physical_technology) {
251     reply_dict[shill::kPhysicalTechnologyProperty] =
252         std::string(physical_technology);
253   }
254 
255   if (service_tethering)
256     reply_dict[shill::kTetheringProperty] = std::string(service_tethering);
257 
258   ServiceProxyMock* service_proxy_mock = new ServiceProxyMock();
259 
260   // Plumb return value into mock object.
261   EXPECT_CALL(*service_proxy_mock, GetProperties(_, _, _))
262       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
263 
264   fake_shill_proxy_->SetServiceForPath(
265       dbus::ObjectPath(service_path),
266       brillo::make_unique_ptr(service_proxy_mock));
267   return service_proxy_mock;
268 }
269 
270 
271 // Query the connection status, type and time last changed, as they were set
272 // during initialization (no signals).
TEST_F(UmRealShillProviderTest,ReadBaseValues)273 TEST_F(UmRealShillProviderTest, ReadBaseValues) {
274   InitWithDefaultService("/");
275   // Query the provider variables.
276   UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_connected());
277   UmTestUtils::ExpectVariableNotSet(provider_->var_conn_type());
278   UmTestUtils::ExpectVariableHasValue(InitTime(),
279                                       provider_->var_conn_last_changed());
280 }
281 
282 // Ensure that invalid DBus paths are ignored.
TEST_F(UmRealShillProviderTest,InvalidServicePath)283 TEST_F(UmRealShillProviderTest, InvalidServicePath) {
284   InitWithDefaultService("invalid");
285   UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_connected());
286   UmTestUtils::ExpectVariableNotSet(provider_->var_conn_type());
287   UmTestUtils::ExpectVariableHasValue(InitTime(),
288                                       provider_->var_conn_last_changed());
289 }
290 
291 // Ensure that a service path property including a different type is ignored.
TEST_F(UmRealShillProviderTest,InvalidServicePathType)292 TEST_F(UmRealShillProviderTest, InvalidServicePathType) {
293   ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_->GetManagerProxy();
294   brillo::VariantDictionary reply_dict;
295   reply_dict[shill::kDefaultServiceProperty] = "/not/an/object/path";
296   EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
297       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
298 
299   EXPECT_TRUE(provider_->Init());
300   EXPECT_TRUE(loop_.RunOnce(false));
301 
302   UmTestUtils::ExpectVariableHasValue(false, provider_->var_is_connected());
303 }
304 
305 // Test that Ethernet connection is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTypeEthernet)306 TEST_F(UmRealShillProviderTest, ReadConnTypeEthernet) {
307   InitWithDefaultService("/");
308   SetupConnectionAndTestType(kFakeEthernetServicePath,
309                              shill::kTypeEthernet,
310                              ConnectionType::kEthernet);
311 }
312 
313 // Test that Wifi connection is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTypeWifi)314 TEST_F(UmRealShillProviderTest, ReadConnTypeWifi) {
315   InitWithDefaultService("/");
316   SetupConnectionAndTestType(kFakeWifiServicePath,
317                              shill::kTypeWifi,
318                              ConnectionType::kWifi);
319 }
320 
321 // Test that Wimax connection is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTypeWimax)322 TEST_F(UmRealShillProviderTest, ReadConnTypeWimax) {
323   InitWithDefaultService("/");
324   SetupConnectionAndTestType(kFakeWimaxServicePath,
325                              shill::kTypeWimax,
326                              ConnectionType::kWimax);
327 }
328 
329 // Test that Bluetooth connection is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTypeBluetooth)330 TEST_F(UmRealShillProviderTest, ReadConnTypeBluetooth) {
331   InitWithDefaultService("/");
332   SetupConnectionAndTestType(kFakeBluetoothServicePath,
333                              shill::kTypeBluetooth,
334                              ConnectionType::kBluetooth);
335 }
336 
337 // Test that Cellular connection is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTypeCellular)338 TEST_F(UmRealShillProviderTest, ReadConnTypeCellular) {
339   InitWithDefaultService("/");
340   SetupConnectionAndTestType(kFakeCellularServicePath,
341                              shill::kTypeCellular,
342                              ConnectionType::kCellular);
343 }
344 
345 // Test that an unknown connection is identified as such.
TEST_F(UmRealShillProviderTest,ReadConnTypeUnknown)346 TEST_F(UmRealShillProviderTest, ReadConnTypeUnknown) {
347   InitWithDefaultService("/");
348   SetupConnectionAndTestType(kFakeUnknownServicePath,
349                              "FooConnectionType",
350                              ConnectionType::kUnknown);
351 }
352 
353 // Tests that VPN connection is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTypeVpn)354 TEST_F(UmRealShillProviderTest, ReadConnTypeVpn) {
355   InitWithDefaultService("/");
356   // Mock logic for returning a default service path and its type.
357   SetServiceReply(kFakeVpnServicePath,
358                   shill::kTypeVPN,
359                   shill::kTypeWifi,
360                   shill::kTetheringNotDetectedState);
361 
362   // Send a signal about a new default service.
363   Time conn_change_time;
364   SendDefaultServiceSignal(kFakeVpnServicePath, &conn_change_time);
365 
366   // Query the connection type, ensure last change time reported correctly.
367   UmTestUtils::ExpectVariableHasValue(ConnectionType::kWifi,
368                                       provider_->var_conn_type());
369   UmTestUtils::ExpectVariableHasValue(conn_change_time,
370                                       provider_->var_conn_last_changed());
371 }
372 
373 // Ensure that the connection type is properly cached in the provider through
374 // subsequent variable readings.
TEST_F(UmRealShillProviderTest,ConnTypeCacheUsed)375 TEST_F(UmRealShillProviderTest, ConnTypeCacheUsed) {
376   InitWithDefaultService("/");
377   SetupConnectionAndTestType(kFakeEthernetServicePath,
378                              shill::kTypeEthernet,
379                              ConnectionType::kEthernet);
380 
381   UmTestUtils::ExpectVariableHasValue(ConnectionType::kEthernet,
382                                       provider_->var_conn_type());
383 }
384 
385 // Ensure that the cached connection type remains valid even when a default
386 // connection signal occurs but the connection is not changed.
TEST_F(UmRealShillProviderTest,ConnTypeCacheRemainsValid)387 TEST_F(UmRealShillProviderTest, ConnTypeCacheRemainsValid) {
388   InitWithDefaultService("/");
389   SetupConnectionAndTestType(kFakeEthernetServicePath,
390                              shill::kTypeEthernet,
391                              ConnectionType::kEthernet);
392 
393   SendDefaultServiceSignal(kFakeEthernetServicePath, nullptr);
394 
395   UmTestUtils::ExpectVariableHasValue(ConnectionType::kEthernet,
396                                       provider_->var_conn_type());
397 }
398 
399 // Ensure that the cached connection type is invalidated and re-read when the
400 // default connection changes.
TEST_F(UmRealShillProviderTest,ConnTypeCacheInvalidated)401 TEST_F(UmRealShillProviderTest, ConnTypeCacheInvalidated) {
402   InitWithDefaultService("/");
403   SetupConnectionAndTestType(kFakeEthernetServicePath,
404                              shill::kTypeEthernet,
405                              ConnectionType::kEthernet);
406 
407   SetupConnectionAndTestType(kFakeWifiServicePath,
408                              shill::kTypeWifi,
409                              ConnectionType::kWifi);
410 }
411 
412 // Test that a non-tethering mode is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTetheringNotDetected)413 TEST_F(UmRealShillProviderTest, ReadConnTetheringNotDetected) {
414   InitWithDefaultService("/");
415   SetupConnectionAndTestTethering(kFakeWifiServicePath,
416                                   shill::kTetheringNotDetectedState,
417                                   ConnectionTethering::kNotDetected);
418 }
419 
420 // Test that a suspected tethering mode is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTetheringSuspected)421 TEST_F(UmRealShillProviderTest, ReadConnTetheringSuspected) {
422   InitWithDefaultService("/");
423   SetupConnectionAndTestTethering(kFakeWifiServicePath,
424                                   shill::kTetheringSuspectedState,
425                                   ConnectionTethering::kSuspected);
426 }
427 
428 // Test that a confirmed tethering mode is identified correctly.
TEST_F(UmRealShillProviderTest,ReadConnTetheringConfirmed)429 TEST_F(UmRealShillProviderTest, ReadConnTetheringConfirmed) {
430   InitWithDefaultService("/");
431   SetupConnectionAndTestTethering(kFakeWifiServicePath,
432                                   shill::kTetheringConfirmedState,
433                                   ConnectionTethering::kConfirmed);
434 }
435 
436 // Test that an unknown tethering mode is identified as such.
TEST_F(UmRealShillProviderTest,ReadConnTetheringUnknown)437 TEST_F(UmRealShillProviderTest, ReadConnTetheringUnknown) {
438   InitWithDefaultService("/");
439   SetupConnectionAndTestTethering(kFakeWifiServicePath,
440                                   "FooConnTethering",
441                                   ConnectionTethering::kUnknown);
442 }
443 
444 // Ensure that the connection tethering mode is properly cached in the provider.
TEST_F(UmRealShillProviderTest,ConnTetheringCacheUsed)445 TEST_F(UmRealShillProviderTest, ConnTetheringCacheUsed) {
446   InitWithDefaultService("/");
447   SetupConnectionAndTestTethering(kFakeEthernetServicePath,
448                                   shill::kTetheringNotDetectedState,
449                                   ConnectionTethering::kNotDetected);
450 
451   UmTestUtils::ExpectVariableHasValue(ConnectionTethering::kNotDetected,
452                                       provider_->var_conn_tethering());
453 }
454 
455 // Ensure that the cached connection tethering mode remains valid even when a
456 // default connection signal occurs but the connection is not changed.
TEST_F(UmRealShillProviderTest,ConnTetheringCacheRemainsValid)457 TEST_F(UmRealShillProviderTest, ConnTetheringCacheRemainsValid) {
458   InitWithDefaultService("/");
459   SetupConnectionAndTestTethering(kFakeEthernetServicePath,
460                                   shill::kTetheringNotDetectedState,
461                                   ConnectionTethering::kNotDetected);
462 
463   SendDefaultServiceSignal(kFakeEthernetServicePath, nullptr);
464 
465   UmTestUtils::ExpectVariableHasValue(ConnectionTethering::kNotDetected,
466                                       provider_->var_conn_tethering());
467 }
468 
469 // Ensure that the cached connection tethering mode is invalidated and re-read
470 // when the default connection changes.
TEST_F(UmRealShillProviderTest,ConnTetheringCacheInvalidated)471 TEST_F(UmRealShillProviderTest, ConnTetheringCacheInvalidated) {
472   InitWithDefaultService("/");
473   SetupConnectionAndTestTethering(kFakeEthernetServicePath,
474                                   shill::kTetheringNotDetectedState,
475                                   ConnectionTethering::kNotDetected);
476 
477   SetupConnectionAndTestTethering(kFakeWifiServicePath,
478                                   shill::kTetheringConfirmedState,
479                                   ConnectionTethering::kConfirmed);
480 }
481 
482 // Fake two DBus signals prompting a default connection change, but otherwise
483 // give the same service path. Check connection status and the time it was last
484 // changed, making sure that it is the time when the first signal was sent (and
485 // not the second).
TEST_F(UmRealShillProviderTest,ReadLastChangedTimeTwoSignals)486 TEST_F(UmRealShillProviderTest, ReadLastChangedTimeTwoSignals) {
487   InitWithDefaultService("/");
488   // Send a default service signal twice, advancing the clock in between.
489   Time conn_change_time;
490   SetupConnectionAndAttrs(kFakeEthernetServicePath,
491                           shill::kTypeEthernet,
492                           shill::kTetheringNotDetectedState,
493                           &conn_change_time);
494   // This will set the service path to the same value, so it should not call
495   // GetProperties() again.
496   SendDefaultServiceSignal(kFakeEthernetServicePath, nullptr);
497 
498   // Query the connection status, ensure last change time reported as the first
499   // time the signal was sent.
500   UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_connected());
501   UmTestUtils::ExpectVariableHasValue(conn_change_time,
502                                       provider_->var_conn_last_changed());
503 }
504 
505 // Make sure that the provider initializes correctly even if shill is not
506 // responding, that variables can be obtained, and that they all return a null
507 // value (indicating that the underlying values were not set).
TEST_F(UmRealShillProviderTest,NoInitConnStatusReadBaseValues)508 TEST_F(UmRealShillProviderTest, NoInitConnStatusReadBaseValues) {
509   // Initialize the provider, no initial connection status response.
510   SetManagerReply(nullptr, false);
511   EXPECT_TRUE(provider_->Init());
512   EXPECT_TRUE(loop_.RunOnce(false));
513   UmTestUtils::ExpectVariableNotSet(provider_->var_is_connected());
514   UmTestUtils::ExpectVariableNotSet(provider_->var_conn_type());
515   UmTestUtils::ExpectVariableNotSet(provider_->var_conn_last_changed());
516 }
517 
518 // Test that, once a signal is received, the connection status and other info
519 // can be read correctly.
TEST_F(UmRealShillProviderTest,NoInitConnStatusReadConnTypeEthernet)520 TEST_F(UmRealShillProviderTest, NoInitConnStatusReadConnTypeEthernet) {
521   // Initialize the provider with no initial connection status response.
522   SetManagerReply(nullptr, false);
523   EXPECT_TRUE(provider_->Init());
524   EXPECT_TRUE(loop_.RunOnce(false));
525 
526   SetupConnectionAndAttrs(kFakeEthernetServicePath,
527                           shill::kTypeEthernet,
528                           shill::kTetheringNotDetectedState,
529                           nullptr);
530   UmTestUtils::ExpectVariableHasValue(true, provider_->var_is_connected());
531 }
532 
533 }  // namespace chromeos_update_manager
534