blob: 15553a5293c4a68264f0730273a91261f832519b [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>
Alex Deymoc705cc82014-02-19 11:15:00 -080012#include <gmock/gmock.h>
Alex Deymo1f012912014-04-24 19:08:04 -070013#include <gtest/gtest.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080014
Alex Deymo41a75a72014-04-15 15:36:22 -070015#include "update_engine/fake_clock.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080016#include "update_engine/policy_manager/default_policy.h"
Gilad Arnold308c1012014-03-12 15:37:06 -070017#include "update_engine/policy_manager/fake_state.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080018#include "update_engine/policy_manager/mock_policy.h"
19#include "update_engine/policy_manager/pmtest_utils.h"
20#include "update_engine/policy_manager/policy_manager.h"
Alex Deymo7b948f02014-03-10 17:01:10 -070021#include "update_engine/test_utils.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080022
Alex Deymo7b948f02014-03-10 17:01:10 -070023using base::Bind;
24using base::Callback;
Alex Deymo41a75a72014-04-15 15:36:22 -070025using chromeos_update_engine::FakeClock;
Alex Deymo7b948f02014-03-10 17:01:10 -070026using std::pair;
Alex Deymoc705cc82014-02-19 11:15:00 -080027using std::string;
Alex Deymo7b948f02014-03-10 17:01:10 -070028using std::vector;
Alex Deymoc705cc82014-02-19 11:15:00 -080029using testing::Return;
30using testing::StrictMock;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080031using testing::_;
32
Alex Deymoc705cc82014-02-19 11:15:00 -080033namespace chromeos_policy_manager {
34
35class PmPolicyManagerTest : public ::testing::Test {
36 protected:
37 virtual void SetUp() {
Alex Deymo42c30c32014-04-24 18:41:18 -070038 fake_state_ = new FakeState();
Alex Deymo680d0222014-04-24 21:00:08 -070039 pmut_.reset(new PolicyManager(&fake_clock_, fake_state_));
Alex Deymoc705cc82014-02-19 11:15:00 -080040 }
41
Alex Deymo680d0222014-04-24 21:00:08 -070042 FakeState* fake_state_; // Owned by the pmut_.
Alex Deymo41a75a72014-04-15 15:36:22 -070043 FakeClock fake_clock_;
Alex Deymo680d0222014-04-24 21:00:08 -070044 scoped_ptr<PolicyManager> pmut_;
Alex Deymoc705cc82014-02-19 11:15:00 -080045};
46
47// The FailingPolicy implements a single method and make it always fail. This
48// class extends the DefaultPolicy class to allow extensions of the Policy
49// class without extending nor changing this test.
50class FailingPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080051 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080052 string* error,
53 bool* result) const {
54 *error = "FailingPolicy failed.";
Alex Deymoe636c3c2014-03-11 19:02:08 -070055 return EvalStatus::kFailed;
Alex Deymoc705cc82014-02-19 11:15:00 -080056 }
57};
58
Alex Deymo7b948f02014-03-10 17:01:10 -070059// The LazyPolicy always returns EvalStatus::kAskMeAgainLater.
Alex Deymoc705cc82014-02-19 11:15:00 -080060class LazyPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080061 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080062 string* error,
63 bool* result) const {
Alex Deymoe636c3c2014-03-11 19:02:08 -070064 return EvalStatus::kAskMeAgainLater;
Alex Deymoc705cc82014-02-19 11:15:00 -080065 }
66};
67
Alex Deymo7b948f02014-03-10 17:01:10 -070068// AccumulateCallsCallback() adds to the passed |acc| accumulator vector pairs
69// of EvalStatus and T instances. This allows to create a callback that keeps
70// track of when it is called and the arguments passed to it, to be used with
71// the PolicyManager::AsyncPolicyRequest().
72template<typename T>
73static void AccumulateCallsCallback(vector<pair<EvalStatus, T>>* acc,
74 EvalStatus status, const T& result) {
75 acc->push_back(std::make_pair(status, result));
76}
77
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -070078TEST_F(PmPolicyManagerTest, PolicyRequestCallReturnsSuccess) {
Alex Deymoc705cc82014-02-19 11:15:00 -080079 bool result;
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -070080 EvalStatus status;
81
82 // Tests that policy requests are completed successfully. It is important that
83 // this test covers all policy requests as defined in Policy.
84 //
85 // TODO(garnold) We may need to adapt this test as the Chrome OS policy grows
86 // beyond the stub implementation.
87 status = pmut_->PolicyRequest(&Policy::UpdateCheckAllowed, &result);
88 EXPECT_EQ(EvalStatus::kSucceeded, status);
89 status = pmut_->PolicyRequest(&Policy::UpdateDownloadAndApplyAllowed,
90 &result);
91 EXPECT_EQ(EvalStatus::kSucceeded, status);
Alex Deymoc705cc82014-02-19 11:15:00 -080092}
93
94TEST_F(PmPolicyManagerTest, PolicyRequestCallsPolicy) {
95 StrictMock<MockPolicy>* policy = new StrictMock<MockPolicy>();
Alex Deymo680d0222014-04-24 21:00:08 -070096 pmut_->set_policy(policy);
Alex Deymoc705cc82014-02-19 11:15:00 -080097 bool result;
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -070098 EvalStatus status;
Alex Deymoc705cc82014-02-19 11:15:00 -080099
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700100 // Tests that the policy methods are actually called on the policy instance.
101 // It is important that this test covers all policy requests as defined in
102 // Policy.
Alex Deymo2de23f52014-02-26 14:30:13 -0800103 EXPECT_CALL(*policy, UpdateCheckAllowed(_, _, _, _))
Alex Deymoe636c3c2014-03-11 19:02:08 -0700104 .WillOnce(Return(EvalStatus::kSucceeded));
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700105 status = pmut_->PolicyRequest(&Policy::UpdateCheckAllowed, &result);
106 EXPECT_EQ(EvalStatus::kSucceeded, status);
107
108 EXPECT_CALL(*policy, UpdateDownloadAndApplyAllowed(_, _, _, _))
109 .WillOnce(Return(EvalStatus::kSucceeded));
110 status = pmut_->PolicyRequest(&Policy::UpdateDownloadAndApplyAllowed,
111 &result);
112 EXPECT_EQ(EvalStatus::kSucceeded, status);
Alex Deymoc705cc82014-02-19 11:15:00 -0800113}
114
115TEST_F(PmPolicyManagerTest, PolicyRequestCallsDefaultOnError) {
Alex Deymo680d0222014-04-24 21:00:08 -0700116 pmut_->set_policy(new FailingPolicy());
Alex Deymoc705cc82014-02-19 11:15:00 -0800117
118 // Tests that the DefaultPolicy instance is called when the method fails,
119 // which will set this as true.
120 bool result = false;
Alex Deymo680d0222014-04-24 21:00:08 -0700121 EvalStatus status = pmut_->PolicyRequest(
122 &Policy::UpdateCheckAllowed, &result);
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700123 EXPECT_EQ(EvalStatus::kSucceeded, status);
Alex Deymoc705cc82014-02-19 11:15:00 -0800124 EXPECT_TRUE(result);
125}
126
127TEST_F(PmPolicyManagerTest, PolicyRequestDoesntBlock) {
Alex Deymo680d0222014-04-24 21:00:08 -0700128 pmut_->set_policy(new LazyPolicy());
Alex Deymoc705cc82014-02-19 11:15:00 -0800129 bool result;
130
Alex Deymo680d0222014-04-24 21:00:08 -0700131 EvalStatus status = pmut_->PolicyRequest(
132 &Policy::UpdateCheckAllowed, &result);
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700133 EXPECT_EQ(EvalStatus::kAskMeAgainLater, status);
Alex Deymoc705cc82014-02-19 11:15:00 -0800134}
135
Alex Deymo7b948f02014-03-10 17:01:10 -0700136TEST_F(PmPolicyManagerTest, AsyncPolicyRequestDelaysEvaluation) {
137 // To avoid differences in code execution order between an AsyncPolicyRequest
138 // call on a policy that returns AskMeAgainLater the first time and one that
139 // succeeds the first time, we ensure that the passed callback is called from
140 // the main loop in both cases even when we could evaluate it right now.
Alex Deymo680d0222014-04-24 21:00:08 -0700141 pmut_->set_policy(new FailingPolicy());
Alex Deymo7b948f02014-03-10 17:01:10 -0700142
143 vector<pair<EvalStatus, bool>> calls;
144 Callback<void(EvalStatus, const bool& result)> callback =
145 Bind(AccumulateCallsCallback<bool>, &calls);
146
Alex Deymo680d0222014-04-24 21:00:08 -0700147 pmut_->AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
Alex Deymo7b948f02014-03-10 17:01:10 -0700148 // The callback should wait until we run the main loop for it to be executed.
149 EXPECT_EQ(0, calls.size());
150 chromeos_update_engine::RunGMainLoopMaxIterations(100);
151 EXPECT_EQ(1, calls.size());
152}
153
Alex Deymoc705cc82014-02-19 11:15:00 -0800154} // namespace chromeos_policy_manager