PolicyManager: UpdateCheckAllowed policy initial implementation.
This patch implements the UpdateCheckAllowed policy for ChromeOS
using the same logic we had on update_check_scheduler.cc. It checks
for updates onces every 45 minutes and does an exponential backoff
up to 4 hours when the update check fails. Some other parts of the
policy are not implemented, such as retry an update check with a
short delay on certain failures.
BUG=chromium:358269
TEST=Unittests added to the policy.
Change-Id: Ief8deff47fd6490bd70a22ba20abed05fcc37ab4
Reviewed-on: https://chromium-review.googlesource.com/197595
Reviewed-by: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/SConstruct b/SConstruct
index 39842ea..2fb23bc 100644
--- a/SConstruct
+++ b/SConstruct
@@ -241,6 +241,7 @@
policy_manager/evaluation_context.cc
policy_manager/event_loop.cc
policy_manager/policy_manager.cc
+ policy_manager/policy.cc
policy_manager/real_config_provider.cc
policy_manager/real_device_policy_provider.cc
policy_manager/real_random_provider.cc
@@ -300,6 +301,7 @@
payload_signer_unittest.cc
payload_state_unittest.cc
policy_manager/boxed_value_unittest.cc
+ policy_manager/chromeos_policy_unittest.cc
policy_manager/evaluation_context_unittest.cc
policy_manager/event_loop_unittest.cc
policy_manager/generic_variables_unittest.cc
diff --git a/policy_manager/chromeos_policy.cc b/policy_manager/chromeos_policy.cc
index 4a9f601..436dc73 100644
--- a/policy_manager/chromeos_policy.cc
+++ b/policy_manager/chromeos_policy.cc
@@ -2,19 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "update_engine/policy_manager/chromeos_policy.h"
+#include "update_engine/policy_manager/policy_utils.h"
+
#include <string>
-#include "update_engine/policy_manager/chromeos_policy.h"
-
+using base::Time;
+using base::TimeDelta;
using std::string;
namespace chromeos_policy_manager {
-EvalStatus ChromeOSPolicy::UpdateCheckAllowed(EvaluationContext* ec,
- State* state, string* error,
- bool* result) const {
- // TODO(deymo): Write this policy implementation with the actual policy.
- *result = true;
+EvalStatus ChromeOSPolicy::UpdateCheckAllowed(
+ EvaluationContext* ec, State* state, string* error,
+ UpdateCheckParams* result) const {
+ Time next_update_check;
+ if (NextUpdateCheckTime(ec, state, error, &next_update_check) !=
+ EvalStatus::kSucceeded) {
+ return EvalStatus::kFailed;
+ }
+
+ if (!ec->IsTimeGreaterThan(next_update_check))
+ return EvalStatus::kAskMeAgainLater;
+
+ // It is time to check for an update.
+ result->updates_enabled = true;
return EvalStatus::kSucceeded;
}
@@ -27,4 +39,66 @@
return EvalStatus::kSucceeded;
}
+EvalStatus ChromeOSPolicy::NextUpdateCheckTime(EvaluationContext* ec,
+ State* state, string* error,
+ Time* next_update_check) const {
+ // Don't check for updates too often. We limit the update checks to once every
+ // some interval. The interval is kTimeoutInitialInterval the first time and
+ // kTimeoutPeriodicInterval for the subsequent update checks. If the update
+ // check fails, we increase the interval between the update checks
+ // exponentially until kTimeoutMaxBackoffInterval. Finally, to avoid having
+ // many chromebooks running update checks at the exact same time, we add some
+ // fuzz to the interval.
+ const Time* updater_started_time =
+ ec->GetValue(state->updater_provider()->var_updater_started_time());
+ POLICY_CHECK_VALUE_AND_FAIL(updater_started_time, error);
+
+ const base::Time* last_checked_time =
+ ec->GetValue(state->updater_provider()->var_last_checked_time());
+
+ const uint64_t* seed = ec->GetValue(state->random_provider()->var_seed());
+ POLICY_CHECK_VALUE_AND_FAIL(seed, error);
+
+ PRNG prng(*seed);
+
+ if (!last_checked_time || *last_checked_time < *updater_started_time) {
+ // First attempt.
+ *next_update_check = *updater_started_time + FuzzedInterval(
+ &prng, kTimeoutInitialInterval, kTimeoutRegularFuzz);
+ return EvalStatus::kSucceeded;
+ }
+ // Check for previous failed attempts to implement the exponential backoff.
+ const unsigned int* consecutive_failed_update_checks = ec->GetValue(
+ state->updater_provider()->var_consecutive_failed_update_checks());
+ POLICY_CHECK_VALUE_AND_FAIL(consecutive_failed_update_checks, error);
+
+ int interval = kTimeoutInitialInterval;
+ for (unsigned int i = 0; i < *consecutive_failed_update_checks; ++i) {
+ interval *= 2;
+ if (interval > kTimeoutMaxBackoffInterval) {
+ interval = kTimeoutMaxBackoffInterval;
+ break;
+ }
+ }
+
+ *next_update_check = *last_checked_time + FuzzedInterval(
+ &prng, interval, kTimeoutRegularFuzz);
+ return EvalStatus::kSucceeded;
+}
+
+TimeDelta ChromeOSPolicy::FuzzedInterval(PRNG* prng, int interval, int fuzz) {
+ int half_fuzz = fuzz / 2;
+ int lower_bound = interval - half_fuzz;
+ int upper_bound = interval + half_fuzz + 1;
+
+ // This guarantees the output interval is non negative.
+ if (lower_bound < 0)
+ lower_bound = 0;
+
+ int fuzzed_interval = lower_bound;
+ if (upper_bound - lower_bound > 0)
+ fuzzed_interval = lower_bound + prng->rand() % (upper_bound - lower_bound);
+ return TimeDelta::FromSeconds(fuzzed_interval);
+}
+
} // namespace chromeos_policy_manager
diff --git a/policy_manager/chromeos_policy.h b/policy_manager/chromeos_policy.h
index 3ade8d0..09d937e 100644
--- a/policy_manager/chromeos_policy.h
+++ b/policy_manager/chromeos_policy.h
@@ -5,7 +5,10 @@
#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_CHROMEOS_POLICY_H_
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_CHROMEOS_POLICY_H_
+#include <gtest/gtest_prod.h> // for FRIEND_TEST
+
#include "update_engine/policy_manager/policy.h"
+#include "update_engine/policy_manager/prng.h"
namespace chromeos_policy_manager {
@@ -16,9 +19,9 @@
virtual ~ChromeOSPolicy() {}
// Policy overrides.
- virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
- std::string* error,
- bool* result) const override;
+ virtual EvalStatus UpdateCheckAllowed(
+ EvaluationContext* ec, State* state, std::string* error,
+ UpdateCheckParams* result) const override;
virtual EvalStatus UpdateDownloadAndApplyAllowed(EvaluationContext* ec,
State* state,
@@ -26,6 +29,31 @@
bool* result) const override;
private:
+ FRIEND_TEST(PmChromeOSPolicyTest,
+ FirstCheckIsAtMostInitialIntervalAfterStart);
+ FRIEND_TEST(PmChromeOSPolicyTest, ExponentialBackoffIsCapped);
+ FRIEND_TEST(PmChromeOSPolicyTest, UpdateCheckAllowedWaitsForTheTimeout);
+
+ // Default update check timeout interval/fuzz values used to compute the
+ // NextUpdateCheckTime(), in seconds. Actual fuzz is within +/- half of the
+ // indicated value.
+ static const int kTimeoutInitialInterval = 7 * 60;
+ static const int kTimeoutPeriodicInterval = 45 * 60;
+ static const int kTimeoutQuickInterval = 1 * 60;
+ static const int kTimeoutMaxBackoffInterval = 4 * 60 * 60;
+ static const int kTimeoutRegularFuzz = 10 * 60;
+
+ // A private policy implementation returning the wallclock timestamp when
+ // the next update check should happen.
+ EvalStatus NextUpdateCheckTime(EvaluationContext* ec, State* state,
+ std::string* error,
+ base::Time* next_update_check) const;
+
+ // Returns a TimeDelta based on the provided |interval| seconds +/- half
+ // |fuzz| seconds. The return value is guaranteed to be a non-negative
+ // TimeDelta.
+ static base::TimeDelta FuzzedInterval(PRNG* prng, int interval, int fuzz);
+
DISALLOW_COPY_AND_ASSIGN(ChromeOSPolicy);
};
diff --git a/policy_manager/chromeos_policy_unittest.cc b/policy_manager/chromeos_policy_unittest.cc
new file mode 100644
index 0000000..c4968ad
--- /dev/null
+++ b/policy_manager/chromeos_policy_unittest.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/policy_manager/chromeos_policy.h"
+
+#include <string>
+
+#include <base/time/time.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/fake_clock.h"
+#include "update_engine/policy_manager/evaluation_context.h"
+#include "update_engine/policy_manager/fake_state.h"
+#include "update_engine/policy_manager/pmtest_utils.h"
+
+using base::Time;
+using base::TimeDelta;
+using chromeos_update_engine::FakeClock;
+using std::string;
+
+namespace chromeos_policy_manager {
+
+class PmChromeOSPolicyTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ SetUpDefaultClock();
+ eval_ctx_ = new EvaluationContext(&fake_clock_);
+ }
+
+ // Sets the clock to fixed values.
+ void SetUpDefaultClock() {
+ fake_clock_.SetMonotonicTime(Time::FromInternalValue(12345678L));
+ fake_clock_.SetWallclockTime(Time::FromInternalValue(12345678901234L));
+ }
+
+ void SetUpDefaultState() {
+ fake_state_.updater_provider()->var_updater_started_time()->reset(
+ new Time(fake_clock_.GetWallclockTime()));
+ fake_state_.updater_provider()->var_last_checked_time()->reset(
+ new Time(fake_clock_.GetWallclockTime()));
+ fake_state_.updater_provider()->var_consecutive_failed_update_checks()->
+ reset(new unsigned int(0));
+
+ fake_state_.random_provider()->var_seed()->reset(
+ new uint64_t(4)); // chosen by fair dice roll.
+ // guaranteed to be random.
+ }
+
+ // Runs the passed |policy_method| policy and expects it to return the
+ // |expected| return value.
+ template<typename T, typename R, typename... Args>
+ void ExpectPolicyStatus(
+ EvalStatus expected,
+ T policy_method,
+ R* result, Args... args) {
+ string error = "<None>";
+ eval_ctx_->ResetEvaluation();
+ EXPECT_EQ(expected,
+ (policy_.*policy_method)(eval_ctx_, &fake_state_, &error, result))
+ << "Returned error: " << error;
+ // TODO(deymo): Dump the context of the EvaluationContext on failure.
+ }
+
+ FakeClock fake_clock_;
+ FakeState fake_state_;
+ scoped_refptr<EvaluationContext> eval_ctx_;
+ ChromeOSPolicy policy_; // ChromeOSPolicy under test.
+};
+
+TEST_F(PmChromeOSPolicyTest, FirstCheckIsAtMostInitialIntervalAfterStart) {
+ Time next_update_check;
+
+ SetUpDefaultState();
+ ExpectPolicyStatus(EvalStatus::kSucceeded,
+ &ChromeOSPolicy::NextUpdateCheckTime, &next_update_check);
+
+ EXPECT_LE(fake_clock_.GetWallclockTime(), next_update_check);
+ EXPECT_GE(fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(
+ ChromeOSPolicy::kTimeoutInitialInterval +
+ ChromeOSPolicy::kTimeoutRegularFuzz), next_update_check);
+}
+
+TEST_F(PmChromeOSPolicyTest, ExponentialBackoffIsCapped) {
+ Time next_update_check;
+
+ SetUpDefaultState();
+ fake_state_.updater_provider()->var_consecutive_failed_update_checks()->
+ reset(new unsigned int(100));
+ ExpectPolicyStatus(EvalStatus::kSucceeded,
+ &ChromeOSPolicy::NextUpdateCheckTime, &next_update_check);
+
+ EXPECT_LE(fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(
+ ChromeOSPolicy::kTimeoutMaxBackoffInterval -
+ ChromeOSPolicy::kTimeoutRegularFuzz - 1), next_update_check);
+ EXPECT_GE(fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(
+ ChromeOSPolicy::kTimeoutMaxBackoffInterval +
+ ChromeOSPolicy::kTimeoutRegularFuzz), next_update_check);
+}
+
+TEST_F(PmChromeOSPolicyTest, UpdateCheckAllowedWaitsForTheTimeout) {
+ // We get the next update_check timestamp from the policy's private method
+ // and then we check the public method respects that value on the normal
+ // case.
+ Time next_update_check;
+ Time last_checked_time =
+ fake_clock_.GetWallclockTime() + TimeDelta::FromMinutes(1234);
+
+ SetUpDefaultClock();
+ SetUpDefaultState();
+ fake_state_.updater_provider()->var_last_checked_time()->reset(
+ new Time(last_checked_time));
+ ExpectPolicyStatus(EvalStatus::kSucceeded,
+ &ChromeOSPolicy::NextUpdateCheckTime, &next_update_check);
+
+ UpdateCheckParams result;
+
+ // Check that the policy blocks until the next_update_check is reached.
+ SetUpDefaultClock();
+ SetUpDefaultState();
+ fake_state_.updater_provider()->var_last_checked_time()->reset(
+ new Time(last_checked_time));
+ fake_clock_.SetWallclockTime(next_update_check - TimeDelta::FromSeconds(1));
+ ExpectPolicyStatus(EvalStatus::kAskMeAgainLater,
+ &Policy::UpdateCheckAllowed, &result);
+
+ SetUpDefaultClock();
+ SetUpDefaultState();
+ fake_state_.updater_provider()->var_last_checked_time()->reset(
+ new Time(last_checked_time));
+ fake_clock_.SetWallclockTime(next_update_check + TimeDelta::FromSeconds(1));
+ ExpectPolicyStatus(EvalStatus::kSucceeded,
+ &Policy::UpdateCheckAllowed, &result);
+}
+
+} // namespace chromeos_policy_manager
diff --git a/policy_manager/default_policy.h b/policy_manager/default_policy.h
index 1eeb54b..e019950 100644
--- a/policy_manager/default_policy.h
+++ b/policy_manager/default_policy.h
@@ -18,10 +18,10 @@
virtual ~DefaultPolicy() {}
// Policy overrides.
- virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
- std::string* error,
- bool* result) const override {
- *result = true;
+ virtual EvalStatus UpdateCheckAllowed(
+ EvaluationContext* ec, State* state, std::string* error,
+ UpdateCheckParams* result) const override {
+ result->updates_enabled = true;
return EvalStatus::kSucceeded;
}
diff --git a/policy_manager/mock_policy.h b/policy_manager/mock_policy.h
index 118a24b..7aa9d66 100644
--- a/policy_manager/mock_policy.h
+++ b/policy_manager/mock_policy.h
@@ -13,20 +13,20 @@
// A mocked implementation of Policy.
class MockPolicy : public Policy {
-public:
+ public:
MockPolicy() {}
virtual ~MockPolicy() {}
// Policy overrides.
MOCK_CONST_METHOD4(UpdateCheckAllowed,
EvalStatus(EvaluationContext*, State*, std::string*,
- bool*));
+ UpdateCheckParams*));
MOCK_CONST_METHOD4(UpdateDownloadAndApplyAllowed,
EvalStatus(EvaluationContext*, State*, std::string*,
bool*));
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(MockPolicy);
};
diff --git a/policy_manager/pmtest_utils.cc b/policy_manager/pmtest_utils.cc
index 569648e..1c53099 100644
--- a/policy_manager/pmtest_utils.cc
+++ b/policy_manager/pmtest_utils.cc
@@ -10,4 +10,8 @@
const unsigned PmTestUtils::kDefaultTimeoutInSeconds = 1;
+void PrintTo(const EvalStatus& status, ::std::ostream* os) {
+ *os << ToString(status);
+}
+
} // namespace chromeos_policy_manager
diff --git a/policy_manager/pmtest_utils.h b/policy_manager/pmtest_utils.h
index d9f98ce..79a7733 100644
--- a/policy_manager/pmtest_utils.h
+++ b/policy_manager/pmtest_utils.h
@@ -5,10 +5,13 @@
#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_PMTEST_UTILS_H_
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_PMTEST_UTILS_H_
+#include <iostream>
+
#include <base/memory/scoped_ptr.h>
#include <base/time/time.h>
#include <gtest/gtest.h>
+#include "update_engine/policy_manager/policy.h"
#include "update_engine/policy_manager/variable.h"
// Convenience macros for checking null-ness of pointers.
@@ -58,6 +61,10 @@
static const unsigned kDefaultTimeoutInSeconds;
};
+// PrintTo() functions are used by gtest to print these values. They need to be
+// defined on the same namespace where the type was defined.
+void PrintTo(const EvalStatus& status, ::std::ostream* os);
+
} // namespace chromeos_policy_manager
#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_PMTEST_UTILS_H_
diff --git a/policy_manager/policy.cc b/policy_manager/policy.cc
new file mode 100644
index 0000000..32c6439
--- /dev/null
+++ b/policy_manager/policy.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "update_engine/policy_manager/policy.h"
+
+#include <string>
+
+using std::string;
+
+namespace chromeos_policy_manager {
+
+string ToString(EvalStatus status) {
+ switch (status) {
+ case EvalStatus::kFailed:
+ return "kFailed";
+ case EvalStatus::kSucceeded:
+ return "kSucceeded";
+ case EvalStatus::kAskMeAgainLater:
+ return "kAskMeAgainLater";
+ }
+ return "Invalid";
+}
+
+} // namespace chromeos_update_engine
diff --git a/policy_manager/policy.h b/policy_manager/policy.h
index 7c7ec0c..334a5bd 100644
--- a/policy_manager/policy.h
+++ b/policy_manager/policy.h
@@ -5,6 +5,8 @@
#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_H_
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_H_
+#include <string>
+
#include "update_engine/policy_manager/evaluation_context.h"
#include "update_engine/policy_manager/state.h"
@@ -17,6 +19,15 @@
kAskMeAgainLater,
};
+std::string ToString(EvalStatus status);
+
+// Parameters of an update check. These parameters are determined by the
+// UpdateCheckAllowed policy.
+struct UpdateCheckParams {
+ bool updates_enabled; // Whether the auto-updates are enabled on this build.
+};
+
+
// The Policy class is an interface to the ensemble of policy requests that the
// client can make. A derived class includes the policy implementations of
// these.
@@ -36,9 +47,9 @@
// UpdateCheckAllowed returns whether it is allowed to request an update check
// to Omaha.
- virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
- std::string* error,
- bool* result) const = 0;
+ virtual EvalStatus UpdateCheckAllowed(
+ EvaluationContext* ec, State* state, std::string* error,
+ UpdateCheckParams* result) const = 0;
// Returns whether an update can be downloaded/applied.
virtual EvalStatus UpdateDownloadAndApplyAllowed(EvaluationContext* ec,
diff --git a/policy_manager/policy_manager_unittest.cc b/policy_manager/policy_manager_unittest.cc
index 15553a5..5272bcd 100644
--- a/policy_manager/policy_manager_unittest.cc
+++ b/policy_manager/policy_manager_unittest.cc
@@ -50,7 +50,7 @@
class FailingPolicy : public DefaultPolicy {
virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
string* error,
- bool* result) const {
+ UpdateCheckParams* result) const {
*error = "FailingPolicy failed.";
return EvalStatus::kFailed;
}
@@ -60,7 +60,7 @@
class LazyPolicy : public DefaultPolicy {
virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
string* error,
- bool* result) const {
+ UpdateCheckParams* result) const {
return EvalStatus::kAskMeAgainLater;
}
};
@@ -75,41 +75,19 @@
acc->push_back(std::make_pair(status, result));
}
-TEST_F(PmPolicyManagerTest, PolicyRequestCallReturnsSuccess) {
+// Tests that policy requests are completed successfully. It is important that
+// this tests cover all policy requests as defined in Policy.
+TEST_F(PmPolicyManagerTest, PolicyRequestCallUpdateDownloadAndApplyAllowed) {
bool result;
- EvalStatus status;
-
- // Tests that policy requests are completed successfully. It is important that
- // this test covers all policy requests as defined in Policy.
- //
- // TODO(garnold) We may need to adapt this test as the Chrome OS policy grows
- // beyond the stub implementation.
- status = pmut_->PolicyRequest(&Policy::UpdateCheckAllowed, &result);
- EXPECT_EQ(EvalStatus::kSucceeded, status);
- status = pmut_->PolicyRequest(&Policy::UpdateDownloadAndApplyAllowed,
- &result);
- EXPECT_EQ(EvalStatus::kSucceeded, status);
+ EXPECT_EQ(EvalStatus::kSucceeded,
+ pmut_->PolicyRequest(&Policy::UpdateDownloadAndApplyAllowed,
+ &result));
}
-TEST_F(PmPolicyManagerTest, PolicyRequestCallsPolicy) {
- StrictMock<MockPolicy>* policy = new StrictMock<MockPolicy>();
- pmut_->set_policy(policy);
- bool result;
- EvalStatus status;
-
- // Tests that the policy methods are actually called on the policy instance.
- // It is important that this test covers all policy requests as defined in
- // Policy.
- EXPECT_CALL(*policy, UpdateCheckAllowed(_, _, _, _))
- .WillOnce(Return(EvalStatus::kSucceeded));
- status = pmut_->PolicyRequest(&Policy::UpdateCheckAllowed, &result);
- EXPECT_EQ(EvalStatus::kSucceeded, status);
-
- EXPECT_CALL(*policy, UpdateDownloadAndApplyAllowed(_, _, _, _))
- .WillOnce(Return(EvalStatus::kSucceeded));
- status = pmut_->PolicyRequest(&Policy::UpdateDownloadAndApplyAllowed,
- &result);
- EXPECT_EQ(EvalStatus::kSucceeded, status);
+TEST_F(PmPolicyManagerTest, PolicyRequestCallUpdateCheckAllowed) {
+ UpdateCheckParams result;
+ EXPECT_EQ(EvalStatus::kSucceeded, pmut_->PolicyRequest(
+ &Policy::UpdateCheckAllowed, &result));
}
TEST_F(PmPolicyManagerTest, PolicyRequestCallsDefaultOnError) {
@@ -117,16 +95,17 @@
// Tests that the DefaultPolicy instance is called when the method fails,
// which will set this as true.
- bool result = false;
+ UpdateCheckParams result;
+ result.updates_enabled = false;
EvalStatus status = pmut_->PolicyRequest(
&Policy::UpdateCheckAllowed, &result);
EXPECT_EQ(EvalStatus::kSucceeded, status);
- EXPECT_TRUE(result);
+ EXPECT_TRUE(result.updates_enabled);
}
TEST_F(PmPolicyManagerTest, PolicyRequestDoesntBlock) {
+ UpdateCheckParams result;
pmut_->set_policy(new LazyPolicy());
- bool result;
EvalStatus status = pmut_->PolicyRequest(
&Policy::UpdateCheckAllowed, &result);
@@ -140,9 +119,9 @@
// the main loop in both cases even when we could evaluate it right now.
pmut_->set_policy(new FailingPolicy());
- vector<pair<EvalStatus, bool>> calls;
- Callback<void(EvalStatus, const bool& result)> callback =
- Bind(AccumulateCallsCallback<bool>, &calls);
+ vector<pair<EvalStatus, UpdateCheckParams>> calls;
+ Callback<void(EvalStatus, const UpdateCheckParams& result)> callback =
+ Bind(AccumulateCallsCallback<UpdateCheckParams>, &calls);
pmut_->AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
// The callback should wait until we run the main loop for it to be executed.
diff --git a/policy_manager/policy_utils.h b/policy_manager/policy_utils.h
new file mode 100644
index 0000000..61e0413
--- /dev/null
+++ b/policy_manager/policy_utils.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_UTILS_H_
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_UTILS_H_
+
+#include "update_engine/policy_manager/policy.h"
+
+// Checks that the passed pointer value is not null, returning kFailed on the
+// current context and setting the *error description when it is null. The
+// intended use is to validate variable failures while using
+// EvaluationContext::GetValue, for example:
+//
+// const int* my_value = ec->GetValue(state->my_provider()->var_my_value());
+// POLICY_CHECK_VALUE_AND_FAIL(my_value, error);
+//
+#define POLICY_CHECK_VALUE_AND_FAIL(ptr, error) \
+ do { \
+ if ((ptr) == nullptr) { \
+ *(error) = #ptr " is required but is null."; \
+ return EvalStatus::kFailed; \
+ } \
+ } while (false)
+
+#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_UTILS_H_