//
// Copyright (C) 2017 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/android_things_policy.h"
#include <memory>
#include "update_engine/update_manager/next_update_check_policy_impl.h"
#include "update_engine/update_manager/policy_test_utils.h"
using base::Time;
using base::TimeDelta;
using chromeos_update_engine::ErrorCode;
using chromeos_update_engine::InstallPlan;
namespace chromeos_update_manager {
class UmAndroidThingsPolicyTest : public UmPolicyTestBase {
protected:
UmAndroidThingsPolicyTest() {
policy_ = std::make_unique<AndroidThingsPolicy>();
}
void SetUpDefaultState() override {
UmPolicyTestBase::SetUpDefaultState();
// For the purpose of the tests, this is an official build
fake_state_.system_provider()->var_is_official_build()->reset(
new bool(true));
// NOLINTNEXTLINE(readability/casting)
fake_state_.system_provider()->var_num_slots()->reset(new unsigned int(2));
}
// Configures the policy to return a desired value from UpdateCheckAllowed by
// faking the current wall clock time as needed. Restores the default state.
// This is used when testing policies that depend on this one.
virtual void SetUpdateCheckAllowed(bool allow_check) {
Time next_update_check;
CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
&next_update_check,
AndroidThingsPolicy::kNextUpdateCheckPolicyConstants);
SetUpDefaultState();
Time curr_time = next_update_check;
if (allow_check)
curr_time += TimeDelta::FromSeconds(1);
else
curr_time -= TimeDelta::FromSeconds(1);
fake_clock_.SetWallclockTime(curr_time);
}
};
TEST_F(UmAndroidThingsPolicyTest, UpdateCheckAllowedWaitsForTheTimeout) {
// We get the next update_check timestamp from the policy's private method
// and then we check the public method respects that value on the normal
// case.
Time next_update_check;
Time last_checked_time =
fake_clock_.GetWallclockTime() + TimeDelta::FromMinutes(1234);
LOG(INFO) << "last_checked_time: " << last_checked_time;
fake_state_.updater_provider()->var_last_checked_time()->reset(
new Time(last_checked_time));
CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
&next_update_check,
AndroidThingsPolicy::kNextUpdateCheckPolicyConstants);
LOG(INFO) << "Next check allowed at: " << next_update_check;
// Check that the policy blocks until the next_update_check is reached.
SetUpDefaultClock();
SetUpDefaultState();
fake_state_.updater_provider()->var_last_checked_time()->reset(
new Time(last_checked_time));
fake_clock_.SetWallclockTime(next_update_check - TimeDelta::FromSeconds(1));
UpdateCheckParams result;
ExpectPolicyStatus(
EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
SetUpDefaultClock();
SetUpDefaultState();
fake_state_.updater_provider()->var_last_checked_time()->reset(
new Time(last_checked_time));
fake_clock_.SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
ExpectPolicyStatus(
EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
EXPECT_TRUE(result.updates_enabled);
EXPECT_FALSE(result.is_interactive);
}
TEST_F(UmAndroidThingsPolicyTest,
UpdateCheckAllowedUpdatesDisabledForUnofficialBuilds) {
// UpdateCheckAllowed should return kAskMeAgainLater if this is an unofficial
// build; we don't want periodic update checks on developer images.
fake_state_.system_provider()->var_is_official_build()->reset(
new bool(false));
UpdateCheckParams result;
ExpectPolicyStatus(
EvalStatus::kAskMeAgainLater, &Policy::UpdateCheckAllowed, &result);
}
TEST_F(UmAndroidThingsPolicyTest,
UpdateCheckAllowedUpdatesDisabledWhenNotEnoughSlotsAbUpdates) {
// UpdateCheckAllowed should return false (kSucceeded) if the image booted
// without enough slots to do A/B updates.
// NOLINTNEXTLINE(readability/casting)
fake_state_.system_provider()->var_num_slots()->reset(new unsigned int(1));
UpdateCheckParams result;
ExpectPolicyStatus(
EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
EXPECT_FALSE(result.updates_enabled);
}
TEST_F(UmAndroidThingsPolicyTest,
UpdateCheckAllowedForcedUpdateRequestedInteractive) {
// UpdateCheckAllowed should return true because a forced update request was
// signaled for an interactive update.
SetUpdateCheckAllowed(true);
fake_state_.updater_provider()->var_forced_update_requested()->reset(
new UpdateRequestStatus(UpdateRequestStatus::kInteractive));
UpdateCheckParams result;
ExpectPolicyStatus(
EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
EXPECT_TRUE(result.updates_enabled);
EXPECT_TRUE(result.is_interactive);
}
TEST_F(UmAndroidThingsPolicyTest,
UpdateCheckAllowedForcedUpdateRequestedPeriodic) {
// UpdateCheckAllowed should return true because a forced update request was
// signaled for a periodic check.
SetUpdateCheckAllowed(true);
fake_state_.updater_provider()->var_forced_update_requested()->reset(
new UpdateRequestStatus(UpdateRequestStatus::kPeriodic));
UpdateCheckParams result;
ExpectPolicyStatus(
EvalStatus::kSucceeded, &Policy::UpdateCheckAllowed, &result);
EXPECT_TRUE(result.updates_enabled);
EXPECT_FALSE(result.is_interactive);
}
TEST_F(UmAndroidThingsPolicyTest, UpdateCanBeAppliedOk) {
// UpdateCanBeApplied should return kSucceeded in the base case
InstallPlan plan;
ErrorCode result;
ExpectPolicyStatus(
EvalStatus::kSucceeded, &Policy::UpdateCanBeApplied, &result, &plan);
EXPECT_EQ(ErrorCode::kSuccess, result);
}
TEST_F(UmAndroidThingsPolicyTest, UpdateCanBeAppliedRestricted) {
// UpdateCanBeApplied should return kOmahaUpdateDeferredPerPolicy in
// when the restricted flag is set in the Updater.
fake_state_.updater_provider()->var_update_restrictions()->reset(
new UpdateRestrictions(UpdateRestrictions::kRestrictDownloading));
InstallPlan plan;
ErrorCode result;
ExpectPolicyStatus(
EvalStatus::kSucceeded, &Policy::UpdateCanBeApplied, &result, &plan);
EXPECT_EQ(ErrorCode::kOmahaUpdateDeferredPerPolicy, result);
}
} // namespace chromeos_update_manager