PolicyManager: Initial support of async PolicyRequests.
This patch adds the new method PolicyManager::AsyncPolicyRequest
that takes a callback to be called once the policy request finishes.
If the given policy request returns kAskMeAgainLater, its evaluation
will be re-scheduled until it returns a given value. On this initial
patch, the evaluation is re-scheduled to happen after a fixed amount
of time instead of using the information collected on the
EvaluationContext.
BUG=chromium:340871
TEST=Unittest added.
Change-Id: If0e2888f26c379b806d811d52c4c3d4a8a6d8efb
Reviewed-on: https://chromium-review.googlesource.com/189636
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/policy_manager/policy_manager_unittest.cc b/policy_manager/policy_manager_unittest.cc
index b9253d3..9e28ebc 100644
--- a/policy_manager/policy_manager_unittest.cc
+++ b/policy_manager/policy_manager_unittest.cc
@@ -2,19 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <base/bind.h>
#include <base/memory/scoped_ptr.h>
#include <base/time.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
-#include <string>
#include "update_engine/policy_manager/default_policy.h"
#include "update_engine/policy_manager/mock_policy.h"
#include "update_engine/policy_manager/pmtest_utils.h"
#include "update_engine/policy_manager/policy_manager.h"
+#include "update_engine/test_utils.h"
+using base::Bind;
+using base::Callback;
using base::TimeDelta;
+using std::pair;
using std::string;
+using std::vector;
using testing::_;
using testing::Return;
@@ -43,7 +52,7 @@
}
};
-// The LazyPolicy always returns
+// The LazyPolicy always returns EvalStatus::kAskMeAgainLater.
class LazyPolicy : public DefaultPolicy {
virtual EvalStatus UpdateCheckAllowed(EvaluationContext* ec, State* state,
string* error,
@@ -52,6 +61,16 @@
}
};
+// AccumulateCallsCallback() adds to the passed |acc| accumulator vector pairs
+// of EvalStatus and T instances. This allows to create a callback that keeps
+// track of when it is called and the arguments passed to it, to be used with
+// the PolicyManager::AsyncPolicyRequest().
+template<typename T>
+static void AccumulateCallsCallback(vector<pair<EvalStatus, T>>* acc,
+ EvalStatus status, const T& result) {
+ acc->push_back(std::make_pair(status, result));
+}
+
TEST_F(PmPolicyManagerTest, PolicyRequestCall) {
bool result;
EvalStatus status = pmut_.PolicyRequest(&Policy::UpdateCheckAllowed, &result);
@@ -89,4 +108,22 @@
EXPECT_EQ(status, EvalStatus::kAskMeAgainLater);
}
+TEST_F(PmPolicyManagerTest, AsyncPolicyRequestDelaysEvaluation) {
+ // To avoid differences in code execution order between an AsyncPolicyRequest
+ // call on a policy that returns AskMeAgainLater the first time and one that
+ // succeeds the first time, we ensure that the passed callback is called from
+ // the main loop in both cases even when we could evaluate it right now.
+ pmut_.policy_.reset(new FailingPolicy());
+
+ vector<pair<EvalStatus, bool>> calls;
+ Callback<void(EvalStatus, const bool& result)> callback =
+ Bind(AccumulateCallsCallback<bool>, &calls);
+
+ pmut_.AsyncPolicyRequest(callback, &Policy::UpdateCheckAllowed);
+ // The callback should wait until we run the main loop for it to be executed.
+ EXPECT_EQ(0, calls.size());
+ chromeos_update_engine::RunGMainLoopMaxIterations(100);
+ EXPECT_EQ(1, calls.size());
+}
+
} // namespace chromeos_policy_manager