blob: e2f3218f06e3e5dd40a8ef2b65150be39db08dc2 [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>
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070011// TODO(garnold) Remove once shill DBus constants not needed.
12#include <chromeos/dbus/service_constants.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080013#include <gtest/gtest.h>
14#include <gmock/gmock.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080015
Gilad Arnold5ef9c482014-03-03 13:51:02 -080016#include "update_engine/fake_clock.h"
17#include "update_engine/mock_dbus_wrapper.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080018#include "update_engine/policy_manager/default_policy.h"
19#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"
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070022// TODO(garnold) Remove once we stop mocking DBus.
Alex Deymo7b948f02014-03-10 17:01:10 -070023#include "update_engine/test_utils.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080024
Alex Deymo7b948f02014-03-10 17:01:10 -070025using base::Bind;
26using base::Callback;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080027using chromeos_update_engine::FakeClock;
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070028using chromeos_update_engine::GValueNewString;
29using chromeos_update_engine::GValueFree;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080030using chromeos_update_engine::MockDBusWrapper;
Alex Deymo7b948f02014-03-10 17:01:10 -070031using std::pair;
Alex Deymoc705cc82014-02-19 11:15:00 -080032using std::string;
Alex Deymo7b948f02014-03-10 17:01:10 -070033using std::vector;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080034using testing::NiceMock;
Alex Deymoc705cc82014-02-19 11:15:00 -080035using testing::Return;
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070036using testing::SetArgPointee;
Alex Deymoc705cc82014-02-19 11:15:00 -080037using testing::StrictMock;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080038using testing::_;
39
40namespace {
41
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070042// TODO(garnold) This whole section gets removed once we mock the shill provider
43// itself in tests.
44
45// Fake dbus-glib objects.
Gilad Arnold5ef9c482014-03-03 13:51:02 -080046DBusGConnection* const kFakeConnection = reinterpret_cast<DBusGConnection*>(1);
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070047DBusGProxy* const kFakeManagerProxy = reinterpret_cast<DBusGProxy*>(2);
Gilad Arnold5ef9c482014-03-03 13:51:02 -080048
49} // namespace
Alex Deymoc705cc82014-02-19 11:15:00 -080050
51namespace chromeos_policy_manager {
52
53class PmPolicyManagerTest : public ::testing::Test {
54 protected:
55 virtual void SetUp() {
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070056 // TODO(garnold) Replace this low-level DBus injection with a high-level
57 // mock shill provider.
58 EXPECT_CALL(mock_dbus_, BusGet(_, _))
59 .WillOnce(Return(kFakeConnection));
60 EXPECT_CALL(mock_dbus_, ProxyNewForName(_, _, _, _))
61 .WillOnce(Return(kFakeManagerProxy));
62 EXPECT_CALL(mock_dbus_, ProxyAddSignal_2(_, _, _, _))
63 .WillOnce(Return());
64 EXPECT_CALL(mock_dbus_, ProxyConnectSignal(_, _, _, _, _))
65 .WillOnce(Return());
66 auto properties = g_hash_table_new_full(g_str_hash, g_str_equal, free,
67 GValueFree);
68 g_hash_table_insert(properties, strdup(shill::kDefaultServiceProperty),
69 GValueNewString("/"));
70 EXPECT_CALL(mock_dbus_, ProxyCall_0_1(_, _, _, _))
71 .WillOnce(DoAll(SetArgPointee<3>(g_hash_table_ref(properties)),
72 Return(true)));
73
Gilad Arnold5ef9c482014-03-03 13:51:02 -080074 EXPECT_TRUE(pmut_.Init(&mock_dbus_, &fake_clock_));
Gilad Arnoldbeb39e92014-03-11 11:34:50 -070075
76 // TODO(garnold) Remove this, too.
77 g_hash_table_unref(properties);
Alex Deymoc705cc82014-02-19 11:15:00 -080078 }
79
Gilad Arnold5ef9c482014-03-03 13:51:02 -080080 NiceMock<MockDBusWrapper> mock_dbus_;
81 FakeClock fake_clock_;
82 PolicyManager pmut_;
Alex Deymoc705cc82014-02-19 11:15:00 -080083};
84
85// The FailingPolicy implements a single method and make it always fail. This
86// class extends the DefaultPolicy class to allow extensions of the Policy
87// class without extending nor changing this test.
88class FailingPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080089 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080090 string* error,
91 bool* result) const {
92 *error = "FailingPolicy failed.";
Alex Deymoe636c3c2014-03-11 19:02:08 -070093 return EvalStatus::kFailed;
Alex Deymoc705cc82014-02-19 11:15:00 -080094 }
95};
96
Alex Deymo7b948f02014-03-10 17:01:10 -070097// The LazyPolicy always returns EvalStatus::kAskMeAgainLater.
Alex Deymoc705cc82014-02-19 11:15:00 -080098class LazyPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080099 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -0800100 string* error,
101 bool* result) const {
Alex Deymoe636c3c2014-03-11 19:02:08 -0700102 return EvalStatus::kAskMeAgainLater;
Alex Deymoc705cc82014-02-19 11:15:00 -0800103 }
104};
105
Alex Deymo7b948f02014-03-10 17:01:10 -0700106// AccumulateCallsCallback() adds to the passed |acc| accumulator vector pairs
107// of EvalStatus and T instances. This allows to create a callback that keeps
108// track of when it is called and the arguments passed to it, to be used with
109// the PolicyManager::AsyncPolicyRequest().
110template<typename T>
111static void AccumulateCallsCallback(vector<pair<EvalStatus, T>>* acc,
112 EvalStatus status, const T& result) {
113 acc->push_back(std::make_pair(status, result));
114}
115
Alex Deymoc705cc82014-02-19 11:15:00 -0800116TEST_F(PmPolicyManagerTest, PolicyRequestCall) {
117 bool result;
118 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700119 EXPECT_EQ(status, EvalStatus::kSucceeded);
Alex Deymoc705cc82014-02-19 11:15:00 -0800120}
121
122TEST_F(PmPolicyManagerTest, PolicyRequestCallsPolicy) {
123 StrictMock<MockPolicy>* policy = new StrictMock<MockPolicy>();
124 pmut_.policy_.reset(policy);
125 bool result;
126
127 // Tests that the method is called on the policy_ instance.
Alex Deymo2de23f52014-02-26 14:30:13 -0800128 EXPECT_CALL(*policy, UpdateCheckAllowed(_, _, _, _))
Alex Deymoe636c3c2014-03-11 19:02:08 -0700129 .WillOnce(Return(EvalStatus::kSucceeded));
Alex Deymoc705cc82014-02-19 11:15:00 -0800130 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700131 EXPECT_EQ(status, EvalStatus::kSucceeded);
Alex Deymoc705cc82014-02-19 11:15:00 -0800132}
133
134TEST_F(PmPolicyManagerTest, PolicyRequestCallsDefaultOnError) {
135 pmut_.policy_.reset(new FailingPolicy());
136
137 // Tests that the DefaultPolicy instance is called when the method fails,
138 // which will set this as true.
139 bool result = false;
140 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700141 EXPECT_EQ(status, EvalStatus::kSucceeded);
Alex Deymoc705cc82014-02-19 11:15:00 -0800142 EXPECT_TRUE(result);
143}
144
145TEST_F(PmPolicyManagerTest, PolicyRequestDoesntBlock) {
146 pmut_.policy_.reset(new LazyPolicy());
147 bool result;
148
149 EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
Alex Deymoe636c3c2014-03-11 19:02:08 -0700150 EXPECT_EQ(status, EvalStatus::kAskMeAgainLater);
Alex Deymoc705cc82014-02-19 11:15:00 -0800151}
152
Alex Deymo7b948f02014-03-10 17:01:10 -0700153TEST_F(PmPolicyManagerTest, AsyncPolicyRequestDelaysEvaluation) {
154 // To avoid differences in code execution order between an AsyncPolicyRequest
155 // call on a policy that returns AskMeAgainLater the first time and one that
156 // succeeds the first time, we ensure that the passed callback is called from
157 // the main loop in both cases even when we could evaluate it right now.
158 pmut_.policy_.reset(new FailingPolicy());
159
160 vector<pair<EvalStatus, bool>> calls;
161 Callback<void(EvalStatus, const bool& result)> callback =
162 Bind(AccumulateCallsCallback<bool>, &calls);
163
164 pmut_.AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
165 // The callback should wait until we run the main loop for it to be executed.
166 EXPECT_EQ(0, calls.size());
167 chromeos_update_engine::RunGMainLoopMaxIterations(100);
168 EXPECT_EQ(1, calls.size());
169}
170
Alex Deymoc705cc82014-02-19 11:15:00 -0800171} // namespace chromeos_policy_manager