PM: Generic variable for copying the return value of a function call.

This is useful for quickly implementing variables that rely on calls to
utility functions/methods.

BUG=None
TEST=Unit tests.

Change-Id: I46040070c417b8c1f7b6081d4fe4d3b43a7a8101
Reviewed-on: https://chromium-review.googlesource.com/200659
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/policy_manager/generic_variables_unittest.cc b/policy_manager/generic_variables_unittest.cc
index 8aad753..279c729 100644
--- a/policy_manager/generic_variables_unittest.cc
+++ b/policy_manager/generic_variables_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "update_engine/policy_manager/generic_variables.h"
 
+#include <base/callback.h>
 #include <base/memory/scoped_ptr.h>
 #include <gtest/gtest.h>
 
@@ -57,11 +58,14 @@
 class CopyConstructorTestClass {
  public:
   CopyConstructorTestClass(void) : copied_(false) {}
-  CopyConstructorTestClass(const CopyConstructorTestClass& /* ignored */)
-      : copied_(true) {}
+  CopyConstructorTestClass(const CopyConstructorTestClass& other)
+      : copied_(true), val_(other.val_ * 2) {}
 
   // Tells if the instance was constructed using the copy-constructor.
-  bool copied_;
+  const bool copied_;
+
+  // An auxiliary internal value.
+  int val_ = 0;
 };
 
 
@@ -91,6 +95,41 @@
 }
 
 
+class PmCallCopyVariableTest : public ::testing::Test {};
+
+CopyConstructorTestClass test_func(CopyConstructorTestClass* obj) {
+  obj->val_++;  // So we can check that the function was called.
+  return *obj;
+}
+
+TEST_F(PmCallCopyVariableTest, SimpleTest) {
+  // Tests that the returned value is generated by copying the value returned by
+  // the function call.
+
+  CopyConstructorTestClass test_obj;
+  ASSERT_FALSE(test_obj.copied_);
+  test_obj.val_ = 5;
+
+  base::Callback<CopyConstructorTestClass(void)> cb = base::Bind(
+      test_func, &test_obj);
+  CallCopyVariable<CopyConstructorTestClass> var("var", cb);
+
+  scoped_ptr<const CopyConstructorTestClass> copy(
+      var.GetValue(PmTestUtils::DefaultTimeout(), nullptr));
+  EXPECT_EQ(6, test_obj.val_);  // Check that the function was called.
+  PMTEST_ASSERT_NOT_NULL(copy.get());
+  EXPECT_TRUE(copy->copied_);
+  EXPECT_EQ(12, copy->val_);  // Check that copying occurred once.
+}
+
+TEST_F(PmCallCopyVariableTest, NullTest) {
+  // Ensures that the variable returns null when the callback is null.
+
+  base::Callback<bool(void)> cb;
+  CallCopyVariable<bool> var("var", cb);
+  PmTestUtils::ExpectVariableNotSet(&var);
+}
+
 class PmAsyncCopyVariableTest : public ::testing::Test {
  public:
   void TearDown() {