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