Home | History | Annotate | Download | only in update_manager
      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 
     17 #include "update_engine/update_manager/real_device_policy_provider.h"
     18 
     19 #include <memory>
     20 
     21 #include <base/memory/ptr_util.h>
     22 #include <brillo/message_loops/fake_message_loop.h>
     23 #include <brillo/message_loops/message_loop.h>
     24 #include <brillo/message_loops/message_loop_utils.h>
     25 #include <gmock/gmock.h>
     26 #include <gtest/gtest.h>
     27 #include <policy/mock_device_policy.h>
     28 #include <policy/mock_libpolicy.h>
     29 #if USE_DBUS
     30 #include <session_manager/dbus-proxies.h>
     31 #include <session_manager/dbus-proxy-mocks.h>
     32 #endif  // USE_DBUS
     33 
     34 #include "update_engine/common/test_utils.h"
     35 #if USE_DBUS
     36 #include "update_engine/dbus_test_utils.h"
     37 #endif  // USE_DBUS
     38 #include "update_engine/update_manager/umtest_utils.h"
     39 
     40 using base::TimeDelta;
     41 using brillo::MessageLoop;
     42 using chromeos_update_engine::ConnectionType;
     43 #if USE_DBUS
     44 using chromeos_update_engine::dbus_test_utils::MockSignalHandler;
     45 #endif  // USE_DBUS
     46 using std::set;
     47 using std::string;
     48 using std::unique_ptr;
     49 using testing::DoAll;
     50 using testing::Mock;
     51 using testing::Return;
     52 using testing::ReturnRef;
     53 using testing::SetArgPointee;
     54 using testing::_;
     55 
     56 namespace chromeos_update_manager {
     57 
     58 class UmRealDevicePolicyProviderTest : public ::testing::Test {
     59  protected:
     60   void SetUp() override {
     61     loop_.SetAsCurrent();
     62 #if USE_DBUS
     63     auto session_manager_proxy_mock =
     64         new org::chromium::SessionManagerInterfaceProxyMock();
     65     provider_.reset(new RealDevicePolicyProvider(
     66         base::WrapUnique(session_manager_proxy_mock), &mock_policy_provider_));
     67 #else
     68     provider_.reset(new RealDevicePolicyProvider(&mock_policy_provider_));
     69 #endif  // USE_DBUS
     70     // By default, we have a device policy loaded. Tests can call
     71     // SetUpNonExistentDevicePolicy() to override this.
     72     SetUpExistentDevicePolicy();
     73 
     74 #if USE_DBUS
     75     // Setup the session manager_proxy such that it will accept the signal
     76     // handler and store it in the |property_change_complete_| once registered.
     77     MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(property_change_complete_,
     78                                               *session_manager_proxy_mock,
     79                                               PropertyChangeComplete);
     80 #endif  // USE_DBUS
     81   }
     82 
     83   void TearDown() override {
     84     provider_.reset();
     85     // Check for leaked callbacks on the main loop.
     86     EXPECT_FALSE(loop_.PendingTasks());
     87   }
     88 
     89   void SetUpNonExistentDevicePolicy() {
     90     ON_CALL(mock_policy_provider_, Reload())
     91         .WillByDefault(Return(false));
     92     ON_CALL(mock_policy_provider_, device_policy_is_loaded())
     93         .WillByDefault(Return(false));
     94     EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0);
     95   }
     96 
     97   void SetUpExistentDevicePolicy() {
     98     // Setup the default behavior of the mocked PolicyProvider.
     99     ON_CALL(mock_policy_provider_, Reload())
    100         .WillByDefault(Return(true));
    101     ON_CALL(mock_policy_provider_, device_policy_is_loaded())
    102         .WillByDefault(Return(true));
    103     ON_CALL(mock_policy_provider_, GetDevicePolicy())
    104         .WillByDefault(ReturnRef(mock_device_policy_));
    105   }
    106 
    107   brillo::FakeMessageLoop loop_{nullptr};
    108   testing::NiceMock<policy::MockDevicePolicy> mock_device_policy_;
    109   testing::NiceMock<policy::MockPolicyProvider> mock_policy_provider_;
    110   unique_ptr<RealDevicePolicyProvider> provider_;
    111 
    112 #if USE_DBUS
    113   // The registered signal handler for the signal.
    114   MockSignalHandler<void(const string&)> property_change_complete_;
    115 #endif  // USE_DBUS
    116 };
    117 
    118 TEST_F(UmRealDevicePolicyProviderTest, RefreshScheduledTest) {
    119   // Check that the RefreshPolicy gets scheduled by checking the TaskId.
    120   EXPECT_TRUE(provider_->Init());
    121   EXPECT_NE(MessageLoop::kTaskIdNull, provider_->scheduled_refresh_);
    122   loop_.RunOnce(false);
    123 }
    124 
    125 TEST_F(UmRealDevicePolicyProviderTest, FirstReload) {
    126   // Checks that the policy is reloaded and the DevicePolicy is consulted twice:
    127   // once on Init() and once again when the signal is connected.
    128   EXPECT_CALL(mock_policy_provider_, Reload());
    129   EXPECT_TRUE(provider_->Init());
    130   Mock::VerifyAndClearExpectations(&mock_policy_provider_);
    131   // We won't be notified that signal is connected without DBus.
    132 #if USE_DBUS
    133   EXPECT_CALL(mock_policy_provider_, Reload());
    134 #endif  // USE_DBUS
    135   loop_.RunOnce(false);
    136 }
    137 
    138 TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded) {
    139   // Checks that the policy is reloaded by RefreshDevicePolicy().
    140   SetUpNonExistentDevicePolicy();
    141   // We won't be notified that signal is connected without DBus.
    142 #if USE_DBUS
    143   EXPECT_CALL(mock_policy_provider_, Reload()).Times(3);
    144 #else
    145   EXPECT_CALL(mock_policy_provider_, Reload()).Times(2);
    146 #endif  // USE_DBUS
    147   EXPECT_TRUE(provider_->Init());
    148   loop_.RunOnce(false);
    149   // Force the policy refresh.
    150   provider_->RefreshDevicePolicy();
    151 }
    152 
    153 #if USE_DBUS
    154 TEST_F(UmRealDevicePolicyProviderTest, SessionManagerSignalForcesReload) {
    155   // Checks that a signal from the SessionManager forces a reload.
    156   SetUpNonExistentDevicePolicy();
    157   EXPECT_CALL(mock_policy_provider_, Reload()).Times(2);
    158   EXPECT_TRUE(provider_->Init());
    159   loop_.RunOnce(false);
    160   Mock::VerifyAndClearExpectations(&mock_policy_provider_);
    161 
    162   EXPECT_CALL(mock_policy_provider_, Reload());
    163   ASSERT_TRUE(property_change_complete_.IsHandlerRegistered());
    164   property_change_complete_.signal_callback().Run("success");
    165 }
    166 #endif  // USE_DBUS
    167 
    168 TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyEmptyVariables) {
    169   SetUpNonExistentDevicePolicy();
    170   EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0);
    171   EXPECT_TRUE(provider_->Init());
    172   loop_.RunOnce(false);
    173 
    174   UmTestUtils::ExpectVariableHasValue(false,
    175                                       provider_->var_device_policy_is_loaded());
    176 
    177   UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel());
    178   UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel_delegated());
    179   UmTestUtils::ExpectVariableNotSet(provider_->var_update_disabled());
    180   UmTestUtils::ExpectVariableNotSet(provider_->var_target_version_prefix());
    181   UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor());
    182   UmTestUtils::ExpectVariableNotSet(
    183       provider_->var_allowed_connection_types_for_update());
    184   UmTestUtils::ExpectVariableNotSet(provider_->var_owner());
    185   UmTestUtils::ExpectVariableNotSet(provider_->var_http_downloads_enabled());
    186   UmTestUtils::ExpectVariableNotSet(provider_->var_au_p2p_enabled());
    187   UmTestUtils::ExpectVariableNotSet(
    188       provider_->var_allow_kiosk_app_control_chrome_version());
    189 }
    190 
    191 TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) {
    192   SetUpNonExistentDevicePolicy();
    193   EXPECT_TRUE(provider_->Init());
    194   loop_.RunOnce(false);
    195   Mock::VerifyAndClearExpectations(&mock_policy_provider_);
    196 
    197   // Reload the policy with a good one and set some values as present. The
    198   // remaining values are false.
    199   SetUpExistentDevicePolicy();
    200   EXPECT_CALL(mock_device_policy_, GetReleaseChannel(_))
    201       .WillOnce(DoAll(SetArgPointee<0>(string("mychannel")), Return(true)));
    202   EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_))
    203       .WillOnce(Return(false));
    204   EXPECT_CALL(mock_device_policy_, GetAllowKioskAppControlChromeVersion(_))
    205       .WillOnce(DoAll(SetArgPointee<0>(true), Return(true)));
    206 
    207   provider_->RefreshDevicePolicy();
    208 
    209   UmTestUtils::ExpectVariableHasValue(true,
    210                                       provider_->var_device_policy_is_loaded());
    211 
    212   // Test that at least one variable is set, to ensure the refresh occurred.
    213   UmTestUtils::ExpectVariableHasValue(string("mychannel"),
    214                                       provider_->var_release_channel());
    215   UmTestUtils::ExpectVariableNotSet(
    216       provider_->var_allowed_connection_types_for_update());
    217   UmTestUtils::ExpectVariableHasValue(
    218       true, provider_->var_allow_kiosk_app_control_chrome_version());
    219 }
    220 
    221 TEST_F(UmRealDevicePolicyProviderTest, ScatterFactorConverted) {
    222   SetUpExistentDevicePolicy();
    223   EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_))
    224 #if USE_DBUS
    225       .Times(2)
    226 #else
    227       .Times(1)
    228 #endif  // USE_DBUS
    229       .WillRepeatedly(DoAll(SetArgPointee<0>(1234), Return(true)));
    230   EXPECT_TRUE(provider_->Init());
    231   loop_.RunOnce(false);
    232 
    233   UmTestUtils::ExpectVariableHasValue(TimeDelta::FromSeconds(1234),
    234                                       provider_->var_scatter_factor());
    235 }
    236 
    237 TEST_F(UmRealDevicePolicyProviderTest, NegativeScatterFactorIgnored) {
    238   SetUpExistentDevicePolicy();
    239   EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_))
    240 #if USE_DBUS
    241       .Times(2)
    242 #else
    243       .Times(1)
    244 #endif  // USE_DBUS
    245       .WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true)));
    246   EXPECT_TRUE(provider_->Init());
    247   loop_.RunOnce(false);
    248 
    249   UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor());
    250 }
    251 
    252 TEST_F(UmRealDevicePolicyProviderTest, AllowedTypesConverted) {
    253   SetUpExistentDevicePolicy();
    254   EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_))
    255 #if USE_DBUS
    256       .Times(2)
    257 #else
    258       .Times(1)
    259 #endif  // USE_DBUS
    260       .WillRepeatedly(DoAll(
    261           SetArgPointee<0>(set<string>{"bluetooth", "wifi", "not-a-type"}),
    262           Return(true)));
    263   EXPECT_TRUE(provider_->Init());
    264   loop_.RunOnce(false);
    265 
    266   UmTestUtils::ExpectVariableHasValue(
    267       set<ConnectionType>{ConnectionType::kWifi, ConnectionType::kBluetooth},
    268       provider_->var_allowed_connection_types_for_update());
    269 }
    270 
    271 }  // namespace chromeos_update_manager
    272