blob: fd430455a7c0695dac64505e4c946745feec2276 [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>
7#include <vector>
8
9#include <base/bind.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080010#include <base/memory/scoped_ptr.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080011#include <gtest/gtest.h>
12#include <gmock/gmock.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080013
Gilad Arnold5ef9c482014-03-03 13:51:02 -080014#include "update_engine/fake_clock.h"
15#include "update_engine/mock_dbus_wrapper.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080016#include "update_engine/policy_manager/default_policy.h"
17#include "update_engine/policy_manager/mock_policy.h"
18#include "update_engine/policy_manager/pmtest_utils.h"
19#include "update_engine/policy_manager/policy_manager.h"
Alex Deymo7b948f02014-03-10 17:01:10 -070020#include "update_engine/test_utils.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080021
Alex Deymo7b948f02014-03-10 17:01:10 -070022using base::Bind;
23using base::Callback;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080024using chromeos_update_engine::FakeClock;
25using chromeos_update_engine::MockDBusWrapper;
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;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080029using testing::NiceMock;
Alex Deymoc705cc82014-02-19 11:15:00 -080030using testing::Return;
31using testing::StrictMock;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080032using testing::_;
33
34namespace {
35
36DBusGConnection* const kFakeConnection = reinterpret_cast<DBusGConnection*>(1);
37
38} // namespace
Alex Deymoc705cc82014-02-19 11:15:00 -080039
40namespace chromeos_policy_manager {
41
42class PmPolicyManagerTest : public ::testing::Test {
43 protected:
44 virtual void SetUp() {
Gilad Arnold5ef9c482014-03-03 13:51:02 -080045 EXPECT_CALL(mock_dbus_, BusGet(_, _)).WillOnce(Return(kFakeConnection));
46 EXPECT_TRUE(pmut_.Init(&mock_dbus_, &fake_clock_));
Alex Deymoc705cc82014-02-19 11:15:00 -080047 }
48
Gilad Arnold5ef9c482014-03-03 13:51:02 -080049 NiceMock<MockDBusWrapper> mock_dbus_;
50 FakeClock fake_clock_;
51 PolicyManager pmut_;
Alex Deymoc705cc82014-02-19 11:15:00 -080052};
53
54// The FailingPolicy implements a single method and make it always fail. This
55// class extends the DefaultPolicy class to allow extensions of the Policy
56// class without extending nor changing this test.
57class FailingPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080058 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080059 string* error,
60 bool* result) const {
61 *error = "FailingPolicy failed.";
Alex Deymoe636c3c2014-03-11 19:02:08 -070062 return EvalStatus::kFailed;
Alex Deymoc705cc82014-02-19 11:15:00 -080063 }
64};
65
Alex Deymo7b948f02014-03-10 17:01:10 -070066// The LazyPolicy always returns EvalStatus::kAskMeAgainLater.
Alex Deymoc705cc82014-02-19 11:15:00 -080067class LazyPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080068 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080069 string* error,
70 bool* result) const {
Alex Deymoe636c3c2014-03-11 19:02:08 -070071 return EvalStatus::kAskMeAgainLater;
Alex Deymoc705cc82014-02-19 11:15:00 -080072 }
73};
74
Alex Deymo7b948f02014-03-10 17:01:10 -070075// AccumulateCallsCallback() adds to the passed |acc| accumulator vector pairs
76// of EvalStatus and T instances. This allows to create a callback that keeps
77// track of when it is called and the arguments passed to it, to be used with
78// the PolicyManager::AsyncPolicyRequest().
79template<typename T>
80static void AccumulateCallsCallback(vector<pair<EvalStatus, T>>* acc,
81 EvalStatus status, const T& result) {
82 acc->push_back(std::make_pair(status, result));
83}
84
Alex Deymoc705cc82014-02-19 11:15:00 -080085TEST_F(PmPolicyManagerTest, PolicyRequestCall) {
86 bool result;
87 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -070088 EXPECT_EQ(status, EvalStatus::kSucceeded);
Alex Deymoc705cc82014-02-19 11:15:00 -080089}
90
91TEST_F(PmPolicyManagerTest, PolicyRequestCallsPolicy) {
92 StrictMock<MockPolicy>* policy = new StrictMock<MockPolicy>();
93 pmut_.policy_.reset(policy);
94 bool result;
95
96 // Tests that the method is called on the policy_ instance.
Alex Deymo2de23f52014-02-26 14:30:13 -080097 EXPECT_CALL(*policy, UpdateCheckAllowed(_, _, _, _))
Alex Deymoe636c3c2014-03-11 19:02:08 -070098 .WillOnce(Return(EvalStatus::kSucceeded));
Alex Deymoc705cc82014-02-19 11:15:00 -080099 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700100 EXPECT_EQ(status, EvalStatus::kSucceeded);
Alex Deymoc705cc82014-02-19 11:15:00 -0800101}
102
103TEST_F(PmPolicyManagerTest, PolicyRequestCallsDefaultOnError) {
104 pmut_.policy_.reset(new FailingPolicy());
105
106 // Tests that the DefaultPolicy instance is called when the method fails,
107 // which will set this as true.
108 bool result = false;
109 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700110 EXPECT_EQ(status, EvalStatus::kSucceeded);
Alex Deymoc705cc82014-02-19 11:15:00 -0800111 EXPECT_TRUE(result);
112}
113
114TEST_F(PmPolicyManagerTest, PolicyRequestDoesntBlock) {
115 pmut_.policy_.reset(new LazyPolicy());
116 bool result;
117
118 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700119 EXPECT_EQ(status, EvalStatus::kAskMeAgainLater);
Alex Deymoc705cc82014-02-19 11:15:00 -0800120}
121
Alex Deymo7b948f02014-03-10 17:01:10 -0700122TEST_F(PmPolicyManagerTest, AsyncPolicyRequestDelaysEvaluation) {
123 // To avoid differences in code execution order between an AsyncPolicyRequest
124 // call on a policy that returns AskMeAgainLater the first time and one that
125 // succeeds the first time, we ensure that the passed callback is called from
126 // the main loop in both cases even when we could evaluate it right now.
127 pmut_.policy_.reset(new FailingPolicy());
128
129 vector<pair<EvalStatus, bool>> calls;
130 Callback<void(EvalStatus, const bool& result)> callback =
131 Bind(AccumulateCallsCallback<bool>, &calls);
132
133 pmut_.AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
134 // The callback should wait until we run the main loop for it to be executed.
135 EXPECT_EQ(0, calls.size());
136 chromeos_update_engine::RunGMainLoopMaxIterations(100);
137 EXPECT_EQ(1, calls.size());
138}
139
Alex Deymoc705cc82014-02-19 11:15:00 -0800140} // namespace chromeos_policy_manager