blob: d56b5a251dddfae6823bf6bba02311969b5fa374 [file] [log] [blame]
Alex Deymo23949d42014-02-05 15:20:59 -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 Deymo23949d42014-02-05 15:20:59 -08005#include <string>
6
Alex Deymo53556ec2014-03-17 10:05:57 -07007#include <base/bind.h>
8#include <base/memory/scoped_ptr.h>
9#include <gtest/gtest.h>
10
Alex Deymo23949d42014-02-05 15:20:59 -080011#include "update_engine/policy_manager/evaluation_context.h"
Alex Deymo53556ec2014-03-17 10:05:57 -070012#include "update_engine/policy_manager/fake_variable.h"
Alex Deymo23949d42014-02-05 15:20:59 -080013#include "update_engine/policy_manager/generic_variables.h"
14#include "update_engine/policy_manager/pmtest_utils.h"
Alex Deymo53556ec2014-03-17 10:05:57 -070015#include "update_engine/test_utils.h"
Alex Deymo23949d42014-02-05 15:20:59 -080016
Alex Deymo53556ec2014-03-17 10:05:57 -070017using base::Bind;
18using base::TimeDelta;
19using chromeos_update_engine::RunGMainLoopMaxIterations;
20using chromeos_update_engine::RunGMainLoopUntil;
Alex Deymo23949d42014-02-05 15:20:59 -080021using std::string;
22
Alex Deymo53556ec2014-03-17 10:05:57 -070023namespace {
24
25void DoNothing() {}
26
27// Sets the value of the passed pointer to true.
28void SetTrue(bool* value) {
29 *value = true;
30}
31
32bool GetBoolean(bool* value) {
33 return *value;
34}
35
36} // namespace
37
Alex Deymo23949d42014-02-05 15:20:59 -080038namespace chromeos_policy_manager {
39
40class PmEvaluationContextTest : public ::testing::Test {
41 public:
Alex Deymo53556ec2014-03-17 10:05:57 -070042 PmEvaluationContextTest() {}
Alex Deymo23949d42014-02-05 15:20:59 -080043
44 protected:
45 virtual void SetUp() {
Alex Deymo7b948f02014-03-10 17:01:10 -070046 eval_ctx_ = new EvaluationContext();
Alex Deymo23949d42014-02-05 15:20:59 -080047 }
48
Alex Deymo53556ec2014-03-17 10:05:57 -070049 virtual void TearDown() {
50 eval_ctx_ = NULL;
51 // Check that the evaluation context removed all the observers.
52 EXPECT_TRUE(fake_int_var_.observer_list_.empty());
53 EXPECT_TRUE(fake_async_var_.observer_list_.empty());
54 EXPECT_TRUE(fake_const_var_.observer_list_.empty());
55 EXPECT_TRUE(fake_poll_var_.observer_list_.empty());
56 }
57
Alex Deymo7b948f02014-03-10 17:01:10 -070058 scoped_refptr<EvaluationContext> eval_ctx_;
Alex Deymo53556ec2014-03-17 10:05:57 -070059
60 // FakeVariables used for testing the EvaluationContext. These are required
61 // here to prevent them from going away *before* the EvaluationContext under
62 // test does, which keeps a reference to them.
63 FakeVariable<int> fake_int_var_ = {"fake_int", kVariableModePoll};
64 FakeVariable<string> fake_async_var_ = {"fake_async", kVariableModeAsync};
65 FakeVariable<string> fake_const_var_ = {"fake_const", kVariableModeConst};
66 FakeVariable<string> fake_poll_var_ = {"fake_poll",
67 TimeDelta::FromSeconds(1)};
Alex Deymo23949d42014-02-05 15:20:59 -080068};
69
70TEST_F(PmEvaluationContextTest, GetValueFails) {
71 // FakeVariable is initialized as returning NULL.
72 PMTEST_EXPECT_NULL(eval_ctx_->GetValue(&fake_int_var_));
73}
74
75TEST_F(PmEvaluationContextTest, GetValueFailsWithInvalidVar) {
76 PMTEST_EXPECT_NULL(eval_ctx_->GetValue(
77 reinterpret_cast<Variable<int>*>(NULL)));
78}
79
80TEST_F(PmEvaluationContextTest, GetValueReturns) {
81 const int* p_fake_int;
82
83 fake_int_var_.reset(new int(42));
84 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
85 PMTEST_ASSERT_NOT_NULL(p_fake_int);
86 EXPECT_EQ(42, *p_fake_int);
87}
88
89TEST_F(PmEvaluationContextTest, GetValueCached) {
90 const int* p_fake_int;
91
92 fake_int_var_.reset(new int(42));
93 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
94
95 // Check that if the variable changes, the EvaluationContext keeps returning
96 // the cached value.
97 fake_int_var_.reset(new int(5));
98
99 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
100 PMTEST_ASSERT_NOT_NULL(p_fake_int);
101 EXPECT_EQ(42, *p_fake_int);
102}
103
104TEST_F(PmEvaluationContextTest, GetValueDontCacheNULL) {
105 const int* p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
106 PMTEST_EXPECT_NULL(p_fake_int);
107
108 fake_int_var_.reset(new int(42));
109 // A second attempt to read the variable should work even on the same
110 // EvaluationContext.
111 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
112 PMTEST_ASSERT_NOT_NULL(p_fake_int);
113 EXPECT_EQ(42, *p_fake_int);
114}
115
116TEST_F(PmEvaluationContextTest, GetValueMixedTypes) {
Alex Deymo23949d42014-02-05 15:20:59 -0800117 const int* p_fake_int;
118 const string* p_fake_string;
119
120 fake_int_var_.reset(new int(42));
Alex Deymo53556ec2014-03-17 10:05:57 -0700121 fake_poll_var_.reset(new string("Hello world!"));
Alex Deymo23949d42014-02-05 15:20:59 -0800122 // Check that the EvaluationContext can handle multiple Variable types. This
123 // is mostly a compile-time check due to the template nature of this method.
124 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
Alex Deymo53556ec2014-03-17 10:05:57 -0700125 p_fake_string = eval_ctx_->GetValue(&fake_poll_var_);
Alex Deymo23949d42014-02-05 15:20:59 -0800126
127 PMTEST_ASSERT_NOT_NULL(p_fake_int);
128 EXPECT_EQ(42, *p_fake_int);
129
130 PMTEST_ASSERT_NOT_NULL(p_fake_string);
131 EXPECT_EQ("Hello world!", *p_fake_string);
132}
133
Alex Deymo53556ec2014-03-17 10:05:57 -0700134// Test that we don't schedule an event if there's no variable to wait for.
135TEST_F(PmEvaluationContextTest, RunOnValueChangeOrTimeoutWithoutVariablesTest) {
136 fake_const_var_.reset(new string("Hello world!"));
137 EXPECT_EQ(*eval_ctx_->GetValue(&fake_const_var_), "Hello world!");
138
139 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
140}
141
142// Test that we don't schedule an event if there's no variable to wait for.
143TEST_F(PmEvaluationContextTest, RunOnValueChangeOrTimeoutWithVariablesTest) {
144 fake_async_var_.reset(new string("Async value"));
145 eval_ctx_->GetValue(&fake_async_var_);
146
147 bool value = false;
148 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
149 // Check that the scheduled callback isn't run until we signal a ValueChaged.
150 RunGMainLoopMaxIterations(100);
151 EXPECT_FALSE(value);
152
153 fake_async_var_.NotifyValueChanged();
154 EXPECT_FALSE(value);
155 // Ensure that the scheduled callback isn't run until we are back on the main
156 // loop.
157 RunGMainLoopMaxIterations(100);
158 EXPECT_TRUE(value);
159}
160
161// Test that we don't re-schedule the events if we are attending one.
162TEST_F(PmEvaluationContextTest, RunOnValueChangeOrTimeoutCalledTwiceTest) {
163 fake_async_var_.reset(new string("Async value"));
164 eval_ctx_->GetValue(&fake_async_var_);
165
166 bool value = false;
167 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
168 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
169
170 // The scheduled event should still work.
171 fake_async_var_.NotifyValueChanged();
172 RunGMainLoopMaxIterations(100);
173 EXPECT_TRUE(value);
174}
175
176// Test that we clear the events when destroying the EvaluationContext.
177TEST_F(PmEvaluationContextTest, RemoveObserversAndTimeoutTest) {
178 fake_async_var_.reset(new string("Async value"));
179 eval_ctx_->GetValue(&fake_async_var_);
180
181 bool value = false;
182 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
183 eval_ctx_ = NULL;
184
185 // This should not trigger the callback since the EvaluationContext waiting
186 // for it is gone, and it should have remove all its observers.
187 fake_async_var_.NotifyValueChanged();
188 RunGMainLoopMaxIterations(100);
189 EXPECT_FALSE(value);
190}
191
192// Test that we don't schedule an event if there's no variable to wait for.
193TEST_F(PmEvaluationContextTest, RunOnValueChangeOrTimeoutRunsFromTimeoutTest) {
194 fake_poll_var_.reset(new string("Polled value"));
195 eval_ctx_->GetValue(&fake_poll_var_);
196
197 bool value = false;
198 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
199 // Check that the scheduled callback isn't run until the timeout occurs.
200 RunGMainLoopMaxIterations(10);
201 EXPECT_FALSE(value);
202 RunGMainLoopUntil(10000, Bind(&GetBoolean, &value));
203 EXPECT_TRUE(value);
204}
205
Alex Deymo23949d42014-02-05 15:20:59 -0800206} // namespace chromeos_policy_manager