Home | History | Annotate | Download | only in update_engine
      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 "update_engine/connection_manager.h"
     18 
     19 #include <set>
     20 #include <string>
     21 
     22 #include <base/logging.h>
     23 #include <brillo/any.h>
     24 #include <brillo/make_unique_ptr.h>
     25 #include <brillo/message_loops/fake_message_loop.h>
     26 #include <brillo/variant_dictionary.h>
     27 #include <gmock/gmock.h>
     28 #include <gtest/gtest.h>
     29 #include <shill/dbus-constants.h>
     30 #include <shill/dbus-proxies.h>
     31 #include <shill/dbus-proxy-mocks.h>
     32 
     33 #include "update_engine/common/test_utils.h"
     34 #include "update_engine/fake_shill_proxy.h"
     35 #include "update_engine/fake_system_state.h"
     36 
     37 using org::chromium::flimflam::ManagerProxyMock;
     38 using org::chromium::flimflam::ServiceProxyMock;
     39 using std::set;
     40 using std::string;
     41 using testing::Return;
     42 using testing::SetArgPointee;
     43 using testing::_;
     44 
     45 namespace chromeos_update_engine {
     46 
     47 class ConnectionManagerTest : public ::testing::Test {
     48  public:
     49   void SetUp() override {
     50     loop_.SetAsCurrent();
     51     fake_system_state_.set_connection_manager(&cmut_);
     52   }
     53 
     54   void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); }
     55 
     56  protected:
     57   // Sets the default_service object path in the response from the
     58   // ManagerProxyMock instance.
     59   void SetManagerReply(const char* default_service, bool reply_succeeds);
     60 
     61   // Sets the |service_type|, |physical_technology| and |service_tethering|
     62   // properties in the mocked service |service_path|. If any of the three
     63   // const char* is a nullptr, the corresponding property will not be included
     64   // in the response.
     65   void SetServiceReply(const string& service_path,
     66                        const char* service_type,
     67                        const char* physical_technology,
     68                        const char* service_tethering);
     69 
     70   void TestWithServiceType(
     71       const char* service_type,
     72       const char* physical_technology,
     73       NetworkConnectionType expected_type);
     74   void TestWithServiceTethering(
     75       const char* service_tethering,
     76       NetworkTethering expected_tethering);
     77 
     78   brillo::FakeMessageLoop loop_{nullptr};
     79   FakeSystemState fake_system_state_;
     80   FakeShillProxy fake_shill_proxy_;
     81 
     82   // ConnectionManager under test.
     83   ConnectionManager cmut_{&fake_shill_proxy_, &fake_system_state_};
     84 };
     85 
     86 void ConnectionManagerTest::SetManagerReply(const char* default_service,
     87                                             bool reply_succeeds) {
     88   ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_.GetManagerProxy();
     89   if (!reply_succeeds) {
     90     EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
     91         .WillOnce(Return(false));
     92     return;
     93   }
     94 
     95   // Create a dictionary of properties and optionally include the default
     96   // service.
     97   brillo::VariantDictionary reply_dict;
     98   reply_dict["SomeOtherProperty"] = 0xC0FFEE;
     99 
    100   if (default_service) {
    101     reply_dict[shill::kDefaultServiceProperty] =
    102         dbus::ObjectPath(default_service);
    103   }
    104   EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
    105       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
    106 }
    107 
    108 void ConnectionManagerTest::SetServiceReply(const string& service_path,
    109                                             const char* service_type,
    110                                             const char* physical_technology,
    111                                             const char* service_tethering) {
    112   brillo::VariantDictionary reply_dict;
    113   reply_dict["SomeOtherProperty"] = 0xC0FFEE;
    114 
    115   if (service_type)
    116     reply_dict[shill::kTypeProperty] = string(service_type);
    117 
    118   if (physical_technology) {
    119     reply_dict[shill::kPhysicalTechnologyProperty] =
    120         string(physical_technology);
    121   }
    122 
    123   if (service_tethering)
    124     reply_dict[shill::kTetheringProperty] = string(service_tethering);
    125 
    126   std::unique_ptr<ServiceProxyMock> service_proxy_mock(new ServiceProxyMock());
    127 
    128   // Plumb return value into mock object.
    129   EXPECT_CALL(*service_proxy_mock.get(), GetProperties(_, _, _))
    130       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
    131 
    132   fake_shill_proxy_.SetServiceForPath(dbus::ObjectPath(service_path),
    133                                       std::move(service_proxy_mock));
    134 }
    135 
    136 void ConnectionManagerTest::TestWithServiceType(
    137     const char* service_type,
    138     const char* physical_technology,
    139     NetworkConnectionType expected_type) {
    140   SetManagerReply("/service/guest/network", true);
    141   SetServiceReply("/service/guest/network",
    142                   service_type,
    143                   physical_technology,
    144                   shill::kTetheringNotDetectedState);
    145 
    146   NetworkConnectionType type;
    147   NetworkTethering tethering;
    148   EXPECT_TRUE(cmut_.GetConnectionProperties(&type, &tethering));
    149   EXPECT_EQ(expected_type, type);
    150   testing::Mock::VerifyAndClearExpectations(
    151       fake_shill_proxy_.GetManagerProxy());
    152 }
    153 
    154 void ConnectionManagerTest::TestWithServiceTethering(
    155     const char* service_tethering,
    156     NetworkTethering expected_tethering) {
    157   SetManagerReply("/service/guest/network", true);
    158   SetServiceReply(
    159       "/service/guest/network", shill::kTypeWifi, nullptr, service_tethering);
    160 
    161   NetworkConnectionType type;
    162   NetworkTethering tethering;
    163   EXPECT_TRUE(cmut_.GetConnectionProperties(&type, &tethering));
    164   EXPECT_EQ(expected_tethering, tethering);
    165   testing::Mock::VerifyAndClearExpectations(
    166       fake_shill_proxy_.GetManagerProxy());
    167 }
    168 
    169 TEST_F(ConnectionManagerTest, SimpleTest) {
    170   TestWithServiceType(shill::kTypeEthernet, nullptr,
    171                       NetworkConnectionType::kEthernet);
    172   TestWithServiceType(shill::kTypeWifi, nullptr,
    173                       NetworkConnectionType::kWifi);
    174   TestWithServiceType(shill::kTypeWimax, nullptr,
    175                       NetworkConnectionType::kWimax);
    176   TestWithServiceType(shill::kTypeBluetooth, nullptr,
    177                       NetworkConnectionType::kBluetooth);
    178   TestWithServiceType(shill::kTypeCellular, nullptr,
    179                       NetworkConnectionType::kCellular);
    180 }
    181 
    182 TEST_F(ConnectionManagerTest, PhysicalTechnologyTest) {
    183   TestWithServiceType(shill::kTypeVPN, nullptr,
    184                       NetworkConnectionType::kUnknown);
    185   TestWithServiceType(shill::kTypeVPN, shill::kTypeVPN,
    186                       NetworkConnectionType::kUnknown);
    187   TestWithServiceType(shill::kTypeVPN, shill::kTypeWifi,
    188                       NetworkConnectionType::kWifi);
    189   TestWithServiceType(shill::kTypeVPN, shill::kTypeWimax,
    190                       NetworkConnectionType::kWimax);
    191 }
    192 
    193 TEST_F(ConnectionManagerTest, TetheringTest) {
    194   TestWithServiceTethering(shill::kTetheringConfirmedState,
    195                            NetworkTethering::kConfirmed);
    196   TestWithServiceTethering(shill::kTetheringNotDetectedState,
    197                            NetworkTethering::kNotDetected);
    198   TestWithServiceTethering(shill::kTetheringSuspectedState,
    199                            NetworkTethering::kSuspected);
    200   TestWithServiceTethering("I'm not a valid property value =)",
    201                            NetworkTethering::kUnknown);
    202 }
    203 
    204 TEST_F(ConnectionManagerTest, UnknownTest) {
    205   TestWithServiceType("foo", nullptr, NetworkConnectionType::kUnknown);
    206 }
    207 
    208 TEST_F(ConnectionManagerTest, AllowUpdatesOverEthernetTest) {
    209   // Updates over Ethernet are allowed even if there's no policy.
    210   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
    211                                         NetworkTethering::kUnknown));
    212 }
    213 
    214 TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) {
    215   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
    216                                         NetworkTethering::kUnknown));
    217 }
    218 
    219 TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) {
    220   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWimax,
    221                                         NetworkTethering::kUnknown));
    222 }
    223 
    224 TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) {
    225   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kBluetooth,
    226                                          NetworkTethering::kUnknown));
    227 }
    228 
    229 TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
    230   policy::MockDevicePolicy allow_3g_policy;
    231 
    232   fake_system_state_.set_device_policy(&allow_3g_policy);
    233 
    234   // This test tests cellular (3G) being the only connection type being allowed.
    235   set<string> allowed_set;
    236   allowed_set.insert(
    237       cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
    238 
    239   EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
    240       .Times(1)
    241       .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(true)));
    242 
    243   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    244                                         NetworkTethering::kUnknown));
    245 }
    246 
    247 TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
    248   policy::MockDevicePolicy allow_3g_policy;
    249 
    250   fake_system_state_.set_device_policy(&allow_3g_policy);
    251 
    252   // This test tests multiple connection types being allowed, with
    253   // 3G one among them. Only Cellular is currently enforced by the policy
    254   // setting, the others are ignored (see Bluetooth for example).
    255   set<string> allowed_set;
    256   allowed_set.insert(
    257       cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
    258   allowed_set.insert(
    259       cmut_.StringForConnectionType(NetworkConnectionType::kBluetooth));
    260 
    261   EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
    262       .Times(3)
    263       .WillRepeatedly(DoAll(SetArgPointee<0>(allowed_set), Return(true)));
    264 
    265   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
    266                                         NetworkTethering::kUnknown));
    267   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
    268                                         NetworkTethering::kNotDetected));
    269   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    270                                         NetworkTethering::kUnknown));
    271   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
    272                                         NetworkTethering::kUnknown));
    273   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWimax,
    274                                         NetworkTethering::kUnknown));
    275   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kBluetooth,
    276                                          NetworkTethering::kUnknown));
    277 
    278   // Tethered networks are treated in the same way as Cellular networks and
    279   // thus allowed.
    280   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
    281                                         NetworkTethering::kConfirmed));
    282   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
    283                                         NetworkTethering::kConfirmed));
    284 }
    285 
    286 TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) {
    287   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    288                                          NetworkTethering::kUnknown));
    289 }
    290 
    291 TEST_F(ConnectionManagerTest, BlockUpdatesOverTetheredNetworkByDefaultTest) {
    292   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
    293                                          NetworkTethering::kConfirmed));
    294   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
    295                                          NetworkTethering::kConfirmed));
    296   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
    297                                         NetworkTethering::kSuspected));
    298 }
    299 
    300 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
    301   policy::MockDevicePolicy block_3g_policy;
    302 
    303   fake_system_state_.set_device_policy(&block_3g_policy);
    304 
    305   // Test that updates for 3G are blocked while updates are allowed
    306   // over several other types.
    307   set<string> allowed_set;
    308   allowed_set.insert(
    309       cmut_.StringForConnectionType(NetworkConnectionType::kEthernet));
    310   allowed_set.insert(
    311       cmut_.StringForConnectionType(NetworkConnectionType::kWifi));
    312   allowed_set.insert(
    313       cmut_.StringForConnectionType(NetworkConnectionType::kWimax));
    314 
    315   EXPECT_CALL(block_3g_policy, GetAllowedConnectionTypesForUpdate(_))
    316       .Times(1)
    317       .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(true)));
    318 
    319   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    320                                          NetworkTethering::kUnknown));
    321 }
    322 
    323 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) {
    324   policy::MockDevicePolicy allow_3g_policy;
    325 
    326   fake_system_state_.set_device_policy(&allow_3g_policy);
    327 
    328   set<string> allowed_set;
    329   allowed_set.insert(
    330       cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
    331 
    332   // Return false for GetAllowedConnectionTypesForUpdate and see
    333   // that updates are still blocked for 3G despite the value being in
    334   // the string set above.
    335   EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
    336       .Times(1)
    337       .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(false)));
    338 
    339   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    340                                          NetworkTethering::kUnknown));
    341 }
    342 
    343 TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) {
    344   policy::MockDevicePolicy no_policy;
    345   testing::NiceMock<MockPrefs>* prefs = fake_system_state_.mock_prefs();
    346 
    347   fake_system_state_.set_device_policy(&no_policy);
    348 
    349   // No setting enforced by the device policy, user prefs should be used.
    350   EXPECT_CALL(no_policy, GetAllowedConnectionTypesForUpdate(_))
    351       .Times(3)
    352       .WillRepeatedly(Return(false));
    353 
    354   // No user pref: block.
    355   EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
    356       .Times(1)
    357       .WillOnce(Return(false));
    358   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    359                                          NetworkTethering::kUnknown));
    360 
    361   // Allow per user pref.
    362   EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
    363       .Times(1)
    364       .WillOnce(Return(true));
    365   EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
    366       .Times(1)
    367       .WillOnce(DoAll(SetArgPointee<1>(true), Return(true)));
    368   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    369                                         NetworkTethering::kUnknown));
    370 
    371   // Block per user pref.
    372   EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
    373       .Times(1)
    374       .WillOnce(Return(true));
    375   EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
    376       .Times(1)
    377       .WillOnce(DoAll(SetArgPointee<1>(false), Return(true)));
    378   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
    379                                          NetworkTethering::kUnknown));
    380 }
    381 
    382 TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) {
    383   EXPECT_STREQ(shill::kTypeEthernet,
    384                cmut_.StringForConnectionType(NetworkConnectionType::kEthernet));
    385   EXPECT_STREQ(shill::kTypeWifi,
    386                cmut_.StringForConnectionType(NetworkConnectionType::kWifi));
    387   EXPECT_STREQ(shill::kTypeWimax,
    388                cmut_.StringForConnectionType(NetworkConnectionType::kWimax));
    389   EXPECT_STREQ(shill::kTypeBluetooth,
    390                cmut_.StringForConnectionType(
    391                    NetworkConnectionType::kBluetooth));
    392   EXPECT_STREQ(shill::kTypeCellular,
    393                cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
    394   EXPECT_STREQ("Unknown",
    395                cmut_.StringForConnectionType(NetworkConnectionType::kUnknown));
    396   EXPECT_STREQ("Unknown",
    397                cmut_.StringForConnectionType(
    398                    static_cast<NetworkConnectionType>(999999)));
    399 }
    400 
    401 TEST_F(ConnectionManagerTest, MalformedServiceList) {
    402   SetManagerReply("/service/guest/network", false);
    403 
    404   NetworkConnectionType type;
    405   NetworkTethering tethering;
    406   EXPECT_FALSE(cmut_.GetConnectionProperties(&type, &tethering));
    407 }
    408 
    409 }  // namespace chromeos_update_engine
    410