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