blob: 89da2a42721c82abe55484cc890896e1a2f44cc5 [file] [log] [blame]
Alex Deymoc705cc82014-02-19 11:15:00 -08001// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymo7b948f02014-03-10 17:01:10 -07005#include <algorithm>
6#include <string>
Alex Deymo94c06162014-03-21 20:34:46 -07007#include <utility>
Alex Deymo7b948f02014-03-10 17:01:10 -07008#include <vector>
9
10#include <base/bind.h>
Alex Deymo680d0222014-04-24 21:00:08 -070011#include <base/memory/scoped_ptr.h>
Gilad Arnoldf62a4b82014-05-01 07:41:07 -070012#include <base/time/time.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080013#include <gmock/gmock.h>
Alex Deymo1f012912014-04-24 19:08:04 -070014#include <gtest/gtest.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080015
Alex Deymo41a75a72014-04-15 15:36:22 -070016#include "update_engine/fake_clock.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080017#include "update_engine/policy_manager/default_policy.h"
Gilad Arnold308c1012014-03-12 15:37:06 -070018#include "update_engine/policy_manager/fake_state.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080019#include "update_engine/policy_manager/mock_policy.h"
20#include "update_engine/policy_manager/pmtest_utils.h"
21#include "update_engine/policy_manager/policy_manager.h"
Alex Deymo7b948f02014-03-10 17:01:10 -070022#include "update_engine/test_utils.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080023
Alex Deymo7b948f02014-03-10 17:01:10 -070024using base::Bind;
25using base::Callback;
Gilad Arnoldf62a4b82014-05-01 07:41:07 -070026using base::Time;
27using base::TimeDelta;
Alex Deymo41a75a72014-04-15 15:36:22 -070028using chromeos_update_engine::FakeClock;
Alex Deymo7b948f02014-03-10 17:01:10 -070029using std::pair;
Alex Deymoc705cc82014-02-19 11:15:00 -080030using std::string;
Alex Deymo7b948f02014-03-10 17:01:10 -070031using std::vector;
Alex Deymoc705cc82014-02-19 11:15:00 -080032using testing::Return;
33using testing::StrictMock;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080034using testing::_;
35
Gilad Arnoldf62a4b82014-05-01 07:41:07 -070036namespace {
37
38// Generates a fixed timestamp for use in faking the current time.
39Time FixedTime() {
40 Time::Exploded now_exp;
41 now_exp.year = 2014;
42 now_exp.month = 3;
43 now_exp.day_of_week = 2;
44 now_exp.day_of_month = 18;
45 now_exp.hour = 8;
46 now_exp.minute = 5;
47 now_exp.second = 33;
48 now_exp.millisecond = 675;
49 return Time::FromLocalExploded(now_exp);
50}
51
52} // namespace
53
Alex Deymoc705cc82014-02-19 11:15:00 -080054namespace chromeos_policy_manager {
55
56class PmPolicyManagerTest : public ::testing::Test {
57 protected:
58 virtual void SetUp() {
Alex Deymo42c30c32014-04-24 18:41:18 -070059 fake_state_ = new FakeState();
Alex Deymo680d0222014-04-24 21:00:08 -070060 pmut_.reset(new PolicyManager(&fake_clock_, fake_state_));
Alex Deymoc705cc82014-02-19 11:15:00 -080061 }
62
Alex Deymo680d0222014-04-24 21:00:08 -070063 FakeState* fake_state_; // Owned by the pmut_.
Alex Deymo41a75a72014-04-15 15:36:22 -070064 FakeClock fake_clock_;
Alex Deymo680d0222014-04-24 21:00:08 -070065 scoped_ptr<PolicyManager> pmut_;
Alex Deymoc705cc82014-02-19 11:15:00 -080066};
67
68// The FailingPolicy implements a single method and make it always fail. This
69// class extends the DefaultPolicy class to allow extensions of the Policy
70// class without extending nor changing this test.
71class FailingPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080072 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080073 string* error,
Alex Deymo0d11c602014-04-23 20:12:20 -070074 UpdateCheckParams* result) const {
Alex Deymoc705cc82014-02-19 11:15:00 -080075 *error = "FailingPolicy failed.";
Alex Deymoe636c3c2014-03-11 19:02:08 -070076 return EvalStatus::kFailed;
Alex Deymoc705cc82014-02-19 11:15:00 -080077 }
78};
79
Alex Deymo7b948f02014-03-10 17:01:10 -070080// The LazyPolicy always returns EvalStatus::kAskMeAgainLater.
Alex Deymoc705cc82014-02-19 11:15:00 -080081class LazyPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080082 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080083 string* error,
Alex Deymo0d11c602014-04-23 20:12:20 -070084 UpdateCheckParams* result) const {
Alex Deymoe636c3c2014-03-11 19:02:08 -070085 return EvalStatus::kAskMeAgainLater;
Alex Deymoc705cc82014-02-19 11:15:00 -080086 }
87};
88
Alex Deymo7b948f02014-03-10 17:01:10 -070089// AccumulateCallsCallback() adds to the passed |acc| accumulator vector pairs
90// of EvalStatus and T instances. This allows to create a callback that keeps
91// track of when it is called and the arguments passed to it, to be used with
92// the PolicyManager::AsyncPolicyRequest().
93template<typename T>
94static void AccumulateCallsCallback(vector<pair<EvalStatus, T>>* acc,
95 EvalStatus status, const T& result) {
96 acc->push_back(std::make_pair(status, result));
97}
98
Alex Deymo0d11c602014-04-23 20:12:20 -070099// Tests that policy requests are completed successfully. It is important that
100// this tests cover all policy requests as defined in Policy.
Alex Deymo0d11c602014-04-23 20:12:20 -0700101TEST_F(PmPolicyManagerTest, PolicyRequestCallUpdateCheckAllowed) {
102 UpdateCheckParams result;
103 EXPECT_EQ(EvalStatus::kSucceeded, pmut_->PolicyRequest(
104 &Policy::UpdateCheckAllowed, &result));
Alex Deymoc705cc82014-02-19 11:15:00 -0800105}
106
Gilad Arnoldf62a4b82014-05-01 07:41:07 -0700107TEST_F(PmPolicyManagerTest, PolicyRequestCallUpdateCanStart) {
108 const UpdateState update_state = {
109 FixedTime(), 1, TimeDelta::FromSeconds(15), TimeDelta::FromSeconds(60),
110 4, 2, 8
111 };
112 UpdateCanStartResult result;
113 EXPECT_EQ(EvalStatus::kSucceeded,
114 pmut_->PolicyRequest(&Policy::UpdateCanStart, &result, true,
115 update_state));
116}
117
Alex Deymoc705cc82014-02-19 11:15:00 -0800118TEST_F(PmPolicyManagerTest, PolicyRequestCallsDefaultOnError) {
Alex Deymo680d0222014-04-24 21:00:08 -0700119 pmut_->set_policy(new FailingPolicy());
Alex Deymoc705cc82014-02-19 11:15:00 -0800120
121 // Tests that the DefaultPolicy instance is called when the method fails,
122 // which will set this as true.
Alex Deymo0d11c602014-04-23 20:12:20 -0700123 UpdateCheckParams result;
124 result.updates_enabled = false;
Alex Deymo680d0222014-04-24 21:00:08 -0700125 EvalStatus status = pmut_->PolicyRequest(
126 &Policy::UpdateCheckAllowed, &result);
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700127 EXPECT_EQ(EvalStatus::kSucceeded, status);
Alex Deymo0d11c602014-04-23 20:12:20 -0700128 EXPECT_TRUE(result.updates_enabled);
Alex Deymoc705cc82014-02-19 11:15:00 -0800129}
130
131TEST_F(PmPolicyManagerTest, PolicyRequestDoesntBlock) {
Alex Deymo0d11c602014-04-23 20:12:20 -0700132 UpdateCheckParams result;
Alex Deymo680d0222014-04-24 21:00:08 -0700133 pmut_->set_policy(new LazyPolicy());
Alex Deymoc705cc82014-02-19 11:15:00 -0800134
Alex Deymo680d0222014-04-24 21:00:08 -0700135 EvalStatus status = pmut_->PolicyRequest(
136 &Policy::UpdateCheckAllowed, &result);
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700137 EXPECT_EQ(EvalStatus::kAskMeAgainLater, status);
Alex Deymoc705cc82014-02-19 11:15:00 -0800138}
139
Alex Deymo7b948f02014-03-10 17:01:10 -0700140TEST_F(PmPolicyManagerTest, AsyncPolicyRequestDelaysEvaluation) {
141 // To avoid differences in code execution order between an AsyncPolicyRequest
142 // call on a policy that returns AskMeAgainLater the first time and one that
143 // succeeds the first time, we ensure that the passed callback is called from
144 // the main loop in both cases even when we could evaluate it right now.
Alex Deymo680d0222014-04-24 21:00:08 -0700145 pmut_->set_policy(new FailingPolicy());
Alex Deymo7b948f02014-03-10 17:01:10 -0700146
Alex Deymo0d11c602014-04-23 20:12:20 -0700147 vector<pair<EvalStatus, UpdateCheckParams>> calls;
148 Callback<void(EvalStatus, const UpdateCheckParams& result)> callback =
149 Bind(AccumulateCallsCallback<UpdateCheckParams>, &calls);
Alex Deymo7b948f02014-03-10 17:01:10 -0700150
Alex Deymo680d0222014-04-24 21:00:08 -0700151 pmut_->AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
Alex Deymo7b948f02014-03-10 17:01:10 -0700152 // The callback should wait until we run the main loop for it to be executed.
153 EXPECT_EQ(0, calls.size());
154 chromeos_update_engine::RunGMainLoopMaxIterations(100);
155 EXPECT_EQ(1, calls.size());
156}
157
Alex Deymoc705cc82014-02-19 11:15:00 -0800158} // namespace chromeos_policy_manager