blob: 4a15e93073e063280dd93f4102beb311cfd3e344 [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 Deymo7b948f02014-03-10 17:01:10 -070017#include "update_engine/test_utils.h"
Alex Deymo63784a52014-05-28 10:46:14 -070018#include "update_engine/update_manager/default_policy.h"
19#include "update_engine/update_manager/fake_state.h"
20#include "update_engine/update_manager/mock_policy.h"
21#include "update_engine/update_manager/umtest_utils.h"
22#include "update_engine/update_manager/update_manager.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;
Gilad Arnoldb3b05442014-05-30 14:25:05 -070028using chromeos_update_engine::ErrorCode;
Alex Deymo41a75a72014-04-15 15:36:22 -070029using chromeos_update_engine::FakeClock;
Alex Deymo7b948f02014-03-10 17:01:10 -070030using std::pair;
Alex Deymoc705cc82014-02-19 11:15:00 -080031using std::string;
Alex Deymo7b948f02014-03-10 17:01:10 -070032using std::vector;
Alex Deymoc705cc82014-02-19 11:15:00 -080033using testing::Return;
34using testing::StrictMock;
Gilad Arnold5ef9c482014-03-03 13:51:02 -080035using testing::_;
36
Gilad Arnoldf62a4b82014-05-01 07:41:07 -070037namespace {
38
39// Generates a fixed timestamp for use in faking the current time.
40Time FixedTime() {
41 Time::Exploded now_exp;
42 now_exp.year = 2014;
43 now_exp.month = 3;
44 now_exp.day_of_week = 2;
45 now_exp.day_of_month = 18;
46 now_exp.hour = 8;
47 now_exp.minute = 5;
48 now_exp.second = 33;
49 now_exp.millisecond = 675;
50 return Time::FromLocalExploded(now_exp);
51}
52
53} // namespace
54
Alex Deymo63784a52014-05-28 10:46:14 -070055namespace chromeos_update_manager {
Alex Deymoc705cc82014-02-19 11:15:00 -080056
Alex Deymo63784a52014-05-28 10:46:14 -070057class UmUpdateManagerTest : public ::testing::Test {
Alex Deymoc705cc82014-02-19 11:15:00 -080058 protected:
59 virtual void SetUp() {
Alex Deymo42c30c32014-04-24 18:41:18 -070060 fake_state_ = new FakeState();
Gilad Arnoldb2271992014-06-19 12:35:24 -070061 umut_.reset(new UpdateManager(&fake_clock_, TimeDelta::FromSeconds(5),
62 fake_state_));
Alex Deymoc705cc82014-02-19 11:15:00 -080063 }
64
Alex Deymo63784a52014-05-28 10:46:14 -070065 FakeState* fake_state_; // Owned by the umut_.
Alex Deymo41a75a72014-04-15 15:36:22 -070066 FakeClock fake_clock_;
Alex Deymo63784a52014-05-28 10:46:14 -070067 scoped_ptr<UpdateManager> umut_;
Alex Deymoc705cc82014-02-19 11:15:00 -080068};
69
70// The FailingPolicy implements a single method and make it always fail. This
71// class extends the DefaultPolicy class to allow extensions of the Policy
72// class without extending nor changing this test.
73class FailingPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080074 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080075 string* error,
Alex Deymo0d11c602014-04-23 20:12:20 -070076 UpdateCheckParams* result) const {
Alex Deymoc705cc82014-02-19 11:15:00 -080077 *error = "FailingPolicy failed.";
Alex Deymoe636c3c2014-03-11 19:02:08 -070078 return EvalStatus::kFailed;
Alex Deymoc705cc82014-02-19 11:15:00 -080079 }
80};
81
Alex Deymo7b948f02014-03-10 17:01:10 -070082// The LazyPolicy always returns EvalStatus::kAskMeAgainLater.
Alex Deymoc705cc82014-02-19 11:15:00 -080083class LazyPolicy : public DefaultPolicy {
Alex Deymo2de23f52014-02-26 14:30:13 -080084 virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
Alex Deymoc705cc82014-02-19 11:15:00 -080085 string* error,
Alex Deymo0d11c602014-04-23 20:12:20 -070086 UpdateCheckParams* result) const {
Alex Deymoe636c3c2014-03-11 19:02:08 -070087 return EvalStatus::kAskMeAgainLater;
Alex Deymoc705cc82014-02-19 11:15:00 -080088 }
89};
90
Alex Deymo7b948f02014-03-10 17:01:10 -070091// AccumulateCallsCallback() adds to the passed |acc| accumulator vector pairs
92// of EvalStatus and T instances. This allows to create a callback that keeps
93// track of when it is called and the arguments passed to it, to be used with
Alex Deymo63784a52014-05-28 10:46:14 -070094// the UpdateManager::AsyncPolicyRequest().
Alex Deymo7b948f02014-03-10 17:01:10 -070095template<typename T>
96static void AccumulateCallsCallback(vector<pair<EvalStatus, T>>* acc,
97 EvalStatus status, const T& result) {
98 acc->push_back(std::make_pair(status, result));
99}
100
Alex Deymo0d11c602014-04-23 20:12:20 -0700101// Tests that policy requests are completed successfully. It is important that
102// this tests cover all policy requests as defined in Policy.
Alex Deymo63784a52014-05-28 10:46:14 -0700103TEST_F(UmUpdateManagerTest, PolicyRequestCallUpdateCheckAllowed) {
Alex Deymo0d11c602014-04-23 20:12:20 -0700104 UpdateCheckParams result;
Alex Deymo63784a52014-05-28 10:46:14 -0700105 EXPECT_EQ(EvalStatus::kSucceeded, umut_->PolicyRequest(
Alex Deymo0d11c602014-04-23 20:12:20 -0700106 &Policy::UpdateCheckAllowed, &result));
Alex Deymoc705cc82014-02-19 11:15:00 -0800107}
108
Alex Deymo63784a52014-05-28 10:46:14 -0700109TEST_F(UmUpdateManagerTest, PolicyRequestCallUpdateCanStart) {
Gilad Arnoldf62a4b82014-05-01 07:41:07 -0700110 const UpdateState update_state = {
Gilad Arnoldb3b05442014-05-30 14:25:05 -0700111 FixedTime(), 1,
112 vector<string>(1, "http://fake/url/"), 10, 0, 0, vector<ErrorCode>(),
113 TimeDelta::FromSeconds(15), TimeDelta::FromSeconds(60),
Gilad Arnoldf62a4b82014-05-01 07:41:07 -0700114 4, 2, 8
115 };
Gilad Arnold42f253b2014-06-25 12:39:17 -0700116 UpdateDownloadParams result;
Gilad Arnoldf62a4b82014-05-01 07:41:07 -0700117 EXPECT_EQ(EvalStatus::kSucceeded,
Alex Deymo63784a52014-05-28 10:46:14 -0700118 umut_->PolicyRequest(&Policy::UpdateCanStart, &result, true,
Gilad Arnoldf62a4b82014-05-01 07:41:07 -0700119 update_state));
120}
121
Alex Deymo63784a52014-05-28 10:46:14 -0700122TEST_F(UmUpdateManagerTest, PolicyRequestCallsDefaultOnError) {
123 umut_->set_policy(new FailingPolicy());
Alex Deymoc705cc82014-02-19 11:15:00 -0800124
125 // Tests that the DefaultPolicy instance is called when the method fails,
126 // which will set this as true.
Alex Deymo0d11c602014-04-23 20:12:20 -0700127 UpdateCheckParams result;
128 result.updates_enabled = false;
Alex Deymo63784a52014-05-28 10:46:14 -0700129 EvalStatus status = umut_->PolicyRequest(
Alex Deymo680d0222014-04-24 21:00:08 -0700130 &Policy::UpdateCheckAllowed, &result);
Gilad Arnoldaf2f6ae2014-04-28 14:14:52 -0700131 EXPECT_EQ(EvalStatus::kSucceeded, status);
Alex Deymo0d11c602014-04-23 20:12:20 -0700132 EXPECT_TRUE(result.updates_enabled);
Alex Deymoc705cc82014-02-19 11:15:00 -0800133}
134
Gilad Arnold897b5e52014-05-21 09:37:18 -0700135// This test only applies to debug builds where DCHECK is enabled.
136#if DCHECK_IS_ON
137TEST_F(UmUpdateManagerTest, PolicyRequestDoesntBlockDeathTest) {
138 // The update manager should die (DCHECK) if a policy called synchronously
139 // returns a kAskMeAgainLater value.
Alex Deymo0d11c602014-04-23 20:12:20 -0700140 UpdateCheckParams result;
Alex Deymo63784a52014-05-28 10:46:14 -0700141 umut_->set_policy(new LazyPolicy());
Gilad Arnold897b5e52014-05-21 09:37:18 -0700142 EXPECT_DEATH(umut_->PolicyRequest(&Policy::UpdateCheckAllowed, &result), "");
Alex Deymoc705cc82014-02-19 11:15:00 -0800143}
Gilad Arnold897b5e52014-05-21 09:37:18 -0700144#endif // DCHECK_IS_ON
Alex Deymoc705cc82014-02-19 11:15:00 -0800145
Alex Deymo63784a52014-05-28 10:46:14 -0700146TEST_F(UmUpdateManagerTest, AsyncPolicyRequestDelaysEvaluation) {
Alex Deymo7b948f02014-03-10 17:01:10 -0700147 // To avoid differences in code execution order between an AsyncPolicyRequest
148 // call on a policy that returns AskMeAgainLater the first time and one that
149 // succeeds the first time, we ensure that the passed callback is called from
150 // the main loop in both cases even when we could evaluate it right now.
Alex Deymo63784a52014-05-28 10:46:14 -0700151 umut_->set_policy(new FailingPolicy());
Alex Deymo7b948f02014-03-10 17:01:10 -0700152
Alex Deymo0d11c602014-04-23 20:12:20 -0700153 vector<pair<EvalStatus, UpdateCheckParams>> calls;
154 Callback<void(EvalStatus, const UpdateCheckParams& result)> callback =
155 Bind(AccumulateCallsCallback<UpdateCheckParams>, &calls);
Alex Deymo7b948f02014-03-10 17:01:10 -0700156
Alex Deymo63784a52014-05-28 10:46:14 -0700157 umut_->AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
Alex Deymo7b948f02014-03-10 17:01:10 -0700158 // The callback should wait until we run the main loop for it to be executed.
159 EXPECT_EQ(0, calls.size());
160 chromeos_update_engine::RunGMainLoopMaxIterations(100);
161 EXPECT_EQ(1, calls.size());
162}
163
Alex Deymo63784a52014-05-28 10:46:14 -0700164} // namespace chromeos_update_manager