//
|
// Copyright (C) 2014 The Android Open Source Project
|
//
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
// you may not use this file except in compliance with the License.
|
// You may obtain a copy of the License at
|
//
|
// http://www.apache.org/licenses/LICENSE-2.0
|
//
|
// Unless required by applicable law or agreed to in writing, software
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// See the License for the specific language governing permissions and
|
// limitations under the License.
|
//
|
|
#include "update_engine/update_manager/real_device_policy_provider.h"
|
|
#include <memory>
|
#include <vector>
|
|
#include <base/memory/ptr_util.h>
|
#include <brillo/message_loops/fake_message_loop.h>
|
#include <brillo/message_loops/message_loop.h>
|
#include <brillo/message_loops/message_loop_utils.h>
|
#include <gmock/gmock.h>
|
#include <gtest/gtest.h>
|
#include <policy/mock_device_policy.h>
|
#include <policy/mock_libpolicy.h>
|
#if USE_DBUS
|
#include <session_manager/dbus-proxies.h>
|
#include <session_manager/dbus-proxy-mocks.h>
|
#endif // USE_DBUS
|
|
#include "update_engine/common/test_utils.h"
|
#if USE_DBUS
|
#include "update_engine/dbus_test_utils.h"
|
#endif // USE_DBUS
|
#include "update_engine/update_manager/umtest_utils.h"
|
|
using base::TimeDelta;
|
using brillo::MessageLoop;
|
using chromeos_update_engine::ConnectionType;
|
using policy::DevicePolicy;
|
#if USE_DBUS
|
using chromeos_update_engine::dbus_test_utils::MockSignalHandler;
|
#endif // USE_DBUS
|
using std::set;
|
using std::string;
|
using std::unique_ptr;
|
using std::vector;
|
using testing::_;
|
using testing::DoAll;
|
using testing::Mock;
|
using testing::Return;
|
using testing::ReturnRef;
|
using testing::SetArgPointee;
|
|
namespace chromeos_update_manager {
|
|
class UmRealDevicePolicyProviderTest : public ::testing::Test {
|
protected:
|
void SetUp() override {
|
loop_.SetAsCurrent();
|
#if USE_DBUS
|
auto session_manager_proxy_mock =
|
new org::chromium::SessionManagerInterfaceProxyMock();
|
provider_.reset(new RealDevicePolicyProvider(
|
base::WrapUnique(session_manager_proxy_mock), &mock_policy_provider_));
|
#else
|
provider_.reset(new RealDevicePolicyProvider(&mock_policy_provider_));
|
#endif // USE_DBUS
|
// By default, we have a device policy loaded. Tests can call
|
// SetUpNonExistentDevicePolicy() to override this.
|
SetUpExistentDevicePolicy();
|
|
#if USE_DBUS
|
// Setup the session manager_proxy such that it will accept the signal
|
// handler and store it in the |property_change_complete_| once registered.
|
MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(property_change_complete_,
|
*session_manager_proxy_mock,
|
PropertyChangeComplete);
|
#endif // USE_DBUS
|
}
|
|
void TearDown() override {
|
provider_.reset();
|
// Check for leaked callbacks on the main loop.
|
EXPECT_FALSE(loop_.PendingTasks());
|
}
|
|
void SetUpNonExistentDevicePolicy() {
|
ON_CALL(mock_policy_provider_, Reload()).WillByDefault(Return(false));
|
ON_CALL(mock_policy_provider_, device_policy_is_loaded())
|
.WillByDefault(Return(false));
|
EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0);
|
}
|
|
void SetUpExistentDevicePolicy() {
|
// Setup the default behavior of the mocked PolicyProvider.
|
ON_CALL(mock_policy_provider_, Reload()).WillByDefault(Return(true));
|
ON_CALL(mock_policy_provider_, device_policy_is_loaded())
|
.WillByDefault(Return(true));
|
ON_CALL(mock_policy_provider_, GetDevicePolicy())
|
.WillByDefault(ReturnRef(mock_device_policy_));
|
}
|
|
brillo::FakeMessageLoop loop_{nullptr};
|
testing::NiceMock<policy::MockDevicePolicy> mock_device_policy_;
|
testing::NiceMock<policy::MockPolicyProvider> mock_policy_provider_;
|
unique_ptr<RealDevicePolicyProvider> provider_;
|
|
#if USE_DBUS
|
// The registered signal handler for the signal.
|
MockSignalHandler<void(const string&)> property_change_complete_;
|
#endif // USE_DBUS
|
};
|
|
TEST_F(UmRealDevicePolicyProviderTest, RefreshScheduledTest) {
|
// Check that the RefreshPolicy gets scheduled by checking the TaskId.
|
EXPECT_TRUE(provider_->Init());
|
EXPECT_NE(MessageLoop::kTaskIdNull, provider_->scheduled_refresh_);
|
loop_.RunOnce(false);
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, FirstReload) {
|
// Checks that the policy is reloaded and the DevicePolicy is consulted twice:
|
// once on Init() and once again when the signal is connected.
|
EXPECT_CALL(mock_policy_provider_, Reload());
|
EXPECT_TRUE(provider_->Init());
|
Mock::VerifyAndClearExpectations(&mock_policy_provider_);
|
// We won't be notified that signal is connected without DBus.
|
#if USE_DBUS
|
EXPECT_CALL(mock_policy_provider_, Reload());
|
#endif // USE_DBUS
|
loop_.RunOnce(false);
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyReloaded) {
|
// Checks that the policy is reloaded by RefreshDevicePolicy().
|
SetUpNonExistentDevicePolicy();
|
// We won't be notified that signal is connected without DBus.
|
#if USE_DBUS
|
EXPECT_CALL(mock_policy_provider_, Reload()).Times(3);
|
#else
|
EXPECT_CALL(mock_policy_provider_, Reload()).Times(2);
|
#endif // USE_DBUS
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
// Force the policy refresh.
|
provider_->RefreshDevicePolicy();
|
}
|
|
#if USE_DBUS
|
TEST_F(UmRealDevicePolicyProviderTest, SessionManagerSignalForcesReload) {
|
// Checks that a signal from the SessionManager forces a reload.
|
SetUpNonExistentDevicePolicy();
|
EXPECT_CALL(mock_policy_provider_, Reload()).Times(2);
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
Mock::VerifyAndClearExpectations(&mock_policy_provider_);
|
|
EXPECT_CALL(mock_policy_provider_, Reload());
|
ASSERT_TRUE(property_change_complete_.IsHandlerRegistered());
|
property_change_complete_.signal_callback().Run("success");
|
}
|
#endif // USE_DBUS
|
|
TEST_F(UmRealDevicePolicyProviderTest, NonExistentDevicePolicyEmptyVariables) {
|
SetUpNonExistentDevicePolicy();
|
EXPECT_CALL(mock_policy_provider_, GetDevicePolicy()).Times(0);
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(false,
|
provider_->var_device_policy_is_loaded());
|
|
UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_release_channel_delegated());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_update_disabled());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_target_version_prefix());
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_rollback_to_target_version());
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_rollback_allowed_milestones());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor());
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_allowed_connection_types_for_update());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_owner());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_http_downloads_enabled());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_au_p2p_enabled());
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_allow_kiosk_app_control_chrome_version());
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_auto_launched_kiosk_app_id());
|
UmTestUtils::ExpectVariableNotSet(provider_->var_disallowed_time_intervals());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, ValuesUpdated) {
|
SetUpNonExistentDevicePolicy();
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
Mock::VerifyAndClearExpectations(&mock_policy_provider_);
|
|
// Reload the policy with a good one and set some values as present. The
|
// remaining values are false.
|
SetUpExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetReleaseChannel(_))
|
.WillOnce(DoAll(SetArgPointee<0>(string("mychannel")), Return(true)));
|
EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_))
|
.WillOnce(Return(false));
|
EXPECT_CALL(mock_device_policy_, GetAllowKioskAppControlChromeVersion(_))
|
.WillOnce(DoAll(SetArgPointee<0>(true), Return(true)));
|
EXPECT_CALL(mock_device_policy_, GetAutoLaunchedKioskAppId(_))
|
.WillOnce(DoAll(SetArgPointee<0>(string("myapp")), Return(true)));
|
|
provider_->RefreshDevicePolicy();
|
|
UmTestUtils::ExpectVariableHasValue(true,
|
provider_->var_device_policy_is_loaded());
|
|
// Test that at least one variable is set, to ensure the refresh occurred.
|
UmTestUtils::ExpectVariableHasValue(string("mychannel"),
|
provider_->var_release_channel());
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_allowed_connection_types_for_update());
|
UmTestUtils::ExpectVariableHasValue(
|
true, provider_->var_allow_kiosk_app_control_chrome_version());
|
UmTestUtils::ExpectVariableHasValue(
|
string("myapp"), provider_->var_auto_launched_kiosk_app_id());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, RollbackToTargetVersionConverted) {
|
SetUpExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetRollbackToTargetVersion(_))
|
#if USE_DBUS
|
.Times(2)
|
#else
|
.Times(1)
|
#endif // USE_DBUS
|
.WillRepeatedly(DoAll(SetArgPointee<0>(2), Return(true)));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(
|
RollbackToTargetVersion::kRollbackAndPowerwash,
|
provider_->var_rollback_to_target_version());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, RollbackAllowedMilestonesOobe) {
|
SetUpNonExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)).Times(0);
|
ON_CALL(mock_policy_provider_, IsConsumerDevice())
|
.WillByDefault(Return(false));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableNotSet(
|
provider_->var_rollback_allowed_milestones());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, RollbackAllowedMilestonesConsumer) {
|
SetUpNonExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_)).Times(0);
|
ON_CALL(mock_policy_provider_, IsConsumerDevice())
|
.WillByDefault(Return(true));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(
|
0, provider_->var_rollback_allowed_milestones());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest,
|
RollbackAllowedMilestonesEnterprisePolicySet) {
|
SetUpExistentDevicePolicy();
|
ON_CALL(mock_device_policy_, GetRollbackAllowedMilestones(_))
|
.WillByDefault(DoAll(SetArgPointee<0>(2), Return(true)));
|
ON_CALL(mock_policy_provider_, IsConsumerDevice())
|
.WillByDefault(Return(false));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(
|
2, provider_->var_rollback_allowed_milestones());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, ScatterFactorConverted) {
|
SetUpExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_))
|
#if USE_DBUS
|
.Times(2)
|
#else
|
.Times(1)
|
#endif // USE_DBUS
|
.WillRepeatedly(DoAll(SetArgPointee<0>(1234), Return(true)));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(TimeDelta::FromSeconds(1234),
|
provider_->var_scatter_factor());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, NegativeScatterFactorIgnored) {
|
SetUpExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetScatterFactorInSeconds(_))
|
#if USE_DBUS
|
.Times(2)
|
#else
|
.Times(1)
|
#endif // USE_DBUS
|
.WillRepeatedly(DoAll(SetArgPointee<0>(-1), Return(true)));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableNotSet(provider_->var_scatter_factor());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, AllowedTypesConverted) {
|
SetUpExistentDevicePolicy();
|
EXPECT_CALL(mock_device_policy_, GetAllowedConnectionTypesForUpdate(_))
|
#if USE_DBUS
|
.Times(2)
|
#else
|
.Times(1)
|
#endif // USE_DBUS
|
.WillRepeatedly(DoAll(
|
SetArgPointee<0>(set<string>{"bluetooth", "wifi", "not-a-type"}),
|
Return(true)));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(
|
set<ConnectionType>{ConnectionType::kWifi, ConnectionType::kBluetooth},
|
provider_->var_allowed_connection_types_for_update());
|
}
|
|
TEST_F(UmRealDevicePolicyProviderTest, DisallowedIntervalsConverted) {
|
SetUpExistentDevicePolicy();
|
|
vector<DevicePolicy::WeeklyTimeInterval> intervals = {
|
{5, TimeDelta::FromHours(5), 6, TimeDelta::FromHours(8)},
|
{1, TimeDelta::FromHours(1), 3, TimeDelta::FromHours(10)}};
|
|
EXPECT_CALL(mock_device_policy_, GetDisallowedTimeIntervals(_))
|
.WillRepeatedly(DoAll(SetArgPointee<0>(intervals), Return(true)));
|
EXPECT_TRUE(provider_->Init());
|
loop_.RunOnce(false);
|
|
UmTestUtils::ExpectVariableHasValue(
|
WeeklyTimeIntervalVector{
|
WeeklyTimeInterval(WeeklyTime(5, TimeDelta::FromHours(5)),
|
WeeklyTime(6, TimeDelta::FromHours(8))),
|
WeeklyTimeInterval(WeeklyTime(1, TimeDelta::FromHours(1)),
|
WeeklyTime(3, TimeDelta::FromHours(10)))},
|
provider_->var_disallowed_time_intervals());
|
}
|
|
} // namespace chromeos_update_manager
|