blob: 014d10cb9def22ded818df75ecdff89f1059d7c2 [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
Ben Chan02f7c1d2014-10-18 15:18:02 -07005#include <memory>
Alex Deymo23949d42014-02-05 15:20:59 -08006#include <string>
7
Alex Deymo53556ec2014-03-17 10:05:57 -07008#include <base/bind.h>
Alex Deymo53556ec2014-03-17 10:05:57 -07009#include <gtest/gtest.h>
10
Alex Deymo41a75a72014-04-15 15:36:22 -070011#include "update_engine/fake_clock.h"
Alex Deymo53556ec2014-03-17 10:05:57 -070012#include "update_engine/test_utils.h"
Alex Deymo63784a52014-05-28 10:46:14 -070013#include "update_engine/update_manager/evaluation_context.h"
14#include "update_engine/update_manager/fake_variable.h"
15#include "update_engine/update_manager/generic_variables.h"
16#include "update_engine/update_manager/mock_variable.h"
17#include "update_engine/update_manager/umtest_utils.h"
Alex Deymo23949d42014-02-05 15:20:59 -080018
Alex Deymo53556ec2014-03-17 10:05:57 -070019using base::Bind;
Gilad Arnoldfb794f42014-07-01 15:36:31 -070020using base::Closure;
Alex Deymo41a75a72014-04-15 15:36:22 -070021using base::Time;
Alex Deymo53556ec2014-03-17 10:05:57 -070022using base::TimeDelta;
Alex Deymo41a75a72014-04-15 15:36:22 -070023using chromeos_update_engine::FakeClock;
Alex Deymo53556ec2014-03-17 10:05:57 -070024using chromeos_update_engine::RunGMainLoopMaxIterations;
25using chromeos_update_engine::RunGMainLoopUntil;
Alex Deymo23949d42014-02-05 15:20:59 -080026using std::string;
Ben Chan02f7c1d2014-10-18 15:18:02 -070027using std::unique_ptr;
Alex Deymo41a75a72014-04-15 15:36:22 -070028using testing::Return;
29using testing::StrictMock;
30using testing::_;
Alex Deymo23949d42014-02-05 15:20:59 -080031
Gilad Arnoldfb794f42014-07-01 15:36:31 -070032namespace chromeos_update_manager {
33
Alex Deymo53556ec2014-03-17 10:05:57 -070034namespace {
35
36void DoNothing() {}
37
38// Sets the value of the passed pointer to true.
39void SetTrue(bool* value) {
40 *value = true;
41}
42
43bool GetBoolean(bool* value) {
44 return *value;
45}
46
Gilad Arnoldfb794f42014-07-01 15:36:31 -070047template<typename T>
48void ReadVar(scoped_refptr<EvaluationContext> ec, Variable<T>* var) {
49 ec->GetValue(var);
50}
Alex Deymo53556ec2014-03-17 10:05:57 -070051
Gilad Arnoldfb794f42014-07-01 15:36:31 -070052// Runs |evaluation|; if the value pointed by |count_p| is greater than zero,
53// decrement it and schedule a reevaluation; otherwise, writes true to |done_p|.
54void EvaluateRepeatedly(Closure evaluation, scoped_refptr<EvaluationContext> ec,
55 int* count_p, bool* done_p) {
56 evaluation.Run();
57
58 // Schedule reevaluation if needed.
59 if (*count_p > 0) {
60 Closure closure = Bind(EvaluateRepeatedly, evaluation, ec, count_p, done_p);
61 ASSERT_TRUE(ec->RunOnValueChangeOrTimeout(closure))
62 << "Failed to schedule reevaluation, count_p=" << *count_p;
63 (*count_p)--;
64 } else {
65 *done_p = true;
66 }
67}
68
69} // namespace
Alex Deymo23949d42014-02-05 15:20:59 -080070
Alex Deymo63784a52014-05-28 10:46:14 -070071class UmEvaluationContextTest : public ::testing::Test {
Alex Deymo23949d42014-02-05 15:20:59 -080072 protected:
73 virtual void SetUp() {
Gilad Arnolda65fced2014-07-23 09:01:31 -070074 // Apr 22, 2009 19:25:00 UTC (this is a random reference point).
75 fake_clock_.SetMonotonicTime(Time::FromTimeT(1240428300));
76 // Mar 2, 2006 1:23:45 UTC.
David Zeuthenc1490282014-04-29 16:25:03 -070077 fake_clock_.SetWallclockTime(Time::FromTimeT(1141262625));
Gilad Arnold83ffdda2014-08-08 13:30:31 -070078 eval_ctx_ = new EvaluationContext(
79 &fake_clock_, default_timeout_, default_timeout_,
Ben Chan02f7c1d2014-10-18 15:18:02 -070080 unique_ptr<base::Callback<void(EvaluationContext*)>>(nullptr));
Alex Deymo23949d42014-02-05 15:20:59 -080081 }
82
Alex Deymo53556ec2014-03-17 10:05:57 -070083 virtual void TearDown() {
Gilad Arnoldfb794f42014-07-01 15:36:31 -070084 // Ensure that the evaluation context did not leak and is actually being
85 // destroyed.
86 if (eval_ctx_) {
87 base::WeakPtr<EvaluationContext> eval_ctx_weak_alias =
88 eval_ctx_->weak_ptr_factory_.GetWeakPtr();
Alex Vakulenko88b591f2014-08-28 16:48:57 -070089 ASSERT_NE(nullptr, eval_ctx_weak_alias.get());
Gilad Arnoldfb794f42014-07-01 15:36:31 -070090 eval_ctx_ = nullptr;
Alex Vakulenko88b591f2014-08-28 16:48:57 -070091 EXPECT_EQ(nullptr, eval_ctx_weak_alias.get())
Gilad Arnoldfb794f42014-07-01 15:36:31 -070092 << "The evaluation context was not destroyed! This is likely a bug "
93 "in how the test was written, look for leaking handles to the EC, "
94 "possibly through closure objects.";
95 }
96
Alex Deymo53556ec2014-03-17 10:05:57 -070097 // Check that the evaluation context removed all the observers.
98 EXPECT_TRUE(fake_int_var_.observer_list_.empty());
99 EXPECT_TRUE(fake_async_var_.observer_list_.empty());
100 EXPECT_TRUE(fake_const_var_.observer_list_.empty());
101 EXPECT_TRUE(fake_poll_var_.observer_list_.empty());
102 }
103
Alex Deymo41a75a72014-04-15 15:36:22 -0700104 base::TimeDelta default_timeout_ = base::TimeDelta::FromSeconds(5);
105
106 FakeClock fake_clock_;
Alex Deymo7b948f02014-03-10 17:01:10 -0700107 scoped_refptr<EvaluationContext> eval_ctx_;
Alex Deymo53556ec2014-03-17 10:05:57 -0700108
109 // FakeVariables used for testing the EvaluationContext. These are required
110 // here to prevent them from going away *before* the EvaluationContext under
111 // test does, which keeps a reference to them.
David Zeuthenc1490282014-04-29 16:25:03 -0700112 FakeVariable<bool> fail_var_ = {"fail_var", kVariableModePoll};
Alex Deymo53556ec2014-03-17 10:05:57 -0700113 FakeVariable<int> fake_int_var_ = {"fake_int", kVariableModePoll};
114 FakeVariable<string> fake_async_var_ = {"fake_async", kVariableModeAsync};
115 FakeVariable<string> fake_const_var_ = {"fake_const", kVariableModeConst};
116 FakeVariable<string> fake_poll_var_ = {"fake_poll",
117 TimeDelta::FromSeconds(1)};
Gilad Arnoldfb794f42014-07-01 15:36:31 -0700118 StrictMock<MockVariable<string>> mock_var_async_ {
119 "mock_var_async", kVariableModeAsync};
120 StrictMock<MockVariable<string>> mock_var_poll_ {
121 "mock_var_poll", kVariableModePoll};
Alex Deymo23949d42014-02-05 15:20:59 -0800122};
123
Alex Deymo63784a52014-05-28 10:46:14 -0700124TEST_F(UmEvaluationContextTest, GetValueFails) {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700125 // FakeVariable is initialized as returning null.
126 EXPECT_EQ(nullptr, eval_ctx_->GetValue(&fake_int_var_));
Alex Deymo23949d42014-02-05 15:20:59 -0800127}
128
Alex Deymo63784a52014-05-28 10:46:14 -0700129TEST_F(UmEvaluationContextTest, GetValueFailsWithInvalidVar) {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700130 EXPECT_EQ(nullptr, eval_ctx_->GetValue(static_cast<Variable<int>*>(nullptr)));
Alex Deymo23949d42014-02-05 15:20:59 -0800131}
132
Alex Deymo63784a52014-05-28 10:46:14 -0700133TEST_F(UmEvaluationContextTest, GetValueReturns) {
Alex Deymo23949d42014-02-05 15:20:59 -0800134 const int* p_fake_int;
135
136 fake_int_var_.reset(new int(42));
137 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700138 ASSERT_NE(nullptr, p_fake_int);
Alex Deymo23949d42014-02-05 15:20:59 -0800139 EXPECT_EQ(42, *p_fake_int);
140}
141
Alex Deymo63784a52014-05-28 10:46:14 -0700142TEST_F(UmEvaluationContextTest, GetValueCached) {
Alex Deymo23949d42014-02-05 15:20:59 -0800143 const int* p_fake_int;
144
145 fake_int_var_.reset(new int(42));
146 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
147
148 // Check that if the variable changes, the EvaluationContext keeps returning
149 // the cached value.
150 fake_int_var_.reset(new int(5));
151
152 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700153 ASSERT_NE(nullptr, p_fake_int);
Alex Deymo23949d42014-02-05 15:20:59 -0800154 EXPECT_EQ(42, *p_fake_int);
155}
156
Alex Deymo63784a52014-05-28 10:46:14 -0700157TEST_F(UmEvaluationContextTest, GetValueCachesNull) {
Alex Deymo23949d42014-02-05 15:20:59 -0800158 const int* p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700159 EXPECT_EQ(nullptr, p_fake_int);
Alex Deymo23949d42014-02-05 15:20:59 -0800160
161 fake_int_var_.reset(new int(42));
Alex Deymocc0e5cf2014-04-23 20:20:11 -0700162 // A second attempt to read the variable should not work because this
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700163 // EvaluationContext already got a null value.
Alex Deymo23949d42014-02-05 15:20:59 -0800164 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700165 EXPECT_EQ(nullptr, p_fake_int);
Alex Deymo23949d42014-02-05 15:20:59 -0800166}
167
Alex Deymo63784a52014-05-28 10:46:14 -0700168TEST_F(UmEvaluationContextTest, GetValueMixedTypes) {
Alex Deymo23949d42014-02-05 15:20:59 -0800169 const int* p_fake_int;
170 const string* p_fake_string;
171
172 fake_int_var_.reset(new int(42));
Alex Deymo53556ec2014-03-17 10:05:57 -0700173 fake_poll_var_.reset(new string("Hello world!"));
Alex Deymo23949d42014-02-05 15:20:59 -0800174 // Check that the EvaluationContext can handle multiple Variable types. This
175 // is mostly a compile-time check due to the template nature of this method.
176 p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
Alex Deymo53556ec2014-03-17 10:05:57 -0700177 p_fake_string = eval_ctx_->GetValue(&fake_poll_var_);
Alex Deymo23949d42014-02-05 15:20:59 -0800178
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700179 ASSERT_NE(nullptr, p_fake_int);
Alex Deymo23949d42014-02-05 15:20:59 -0800180 EXPECT_EQ(42, *p_fake_int);
181
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700182 ASSERT_NE(nullptr, p_fake_string);
Alex Deymo23949d42014-02-05 15:20:59 -0800183 EXPECT_EQ("Hello world!", *p_fake_string);
184}
185
Alex Deymo53556ec2014-03-17 10:05:57 -0700186// Test that we don't schedule an event if there's no variable to wait for.
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700187TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutWithoutVariables) {
Alex Deymo53556ec2014-03-17 10:05:57 -0700188 fake_const_var_.reset(new string("Hello world!"));
189 EXPECT_EQ(*eval_ctx_->GetValue(&fake_const_var_), "Hello world!");
190
191 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
192}
193
Gilad Arnoldfb794f42014-07-01 15:36:31 -0700194// Test that reevaluation occurs when an async variable it depends on changes.
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700195TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutWithVariables) {
Alex Deymo53556ec2014-03-17 10:05:57 -0700196 fake_async_var_.reset(new string("Async value"));
197 eval_ctx_->GetValue(&fake_async_var_);
198
199 bool value = false;
200 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
201 // Check that the scheduled callback isn't run until we signal a ValueChaged.
202 RunGMainLoopMaxIterations(100);
203 EXPECT_FALSE(value);
204
205 fake_async_var_.NotifyValueChanged();
206 EXPECT_FALSE(value);
207 // Ensure that the scheduled callback isn't run until we are back on the main
208 // loop.
209 RunGMainLoopMaxIterations(100);
210 EXPECT_TRUE(value);
211}
212
213// Test that we don't re-schedule the events if we are attending one.
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700214TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutCalledTwice) {
Alex Deymo53556ec2014-03-17 10:05:57 -0700215 fake_async_var_.reset(new string("Async value"));
216 eval_ctx_->GetValue(&fake_async_var_);
217
218 bool value = false;
219 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
220 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
221
222 // The scheduled event should still work.
223 fake_async_var_.NotifyValueChanged();
224 RunGMainLoopMaxIterations(100);
225 EXPECT_TRUE(value);
226}
227
Gilad Arnoldfb794f42014-07-01 15:36:31 -0700228// Test that reevaluation occurs when a polling timeout fires.
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700229TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutRunsFromTimeout) {
Alex Deymo53556ec2014-03-17 10:05:57 -0700230 fake_poll_var_.reset(new string("Polled value"));
231 eval_ctx_->GetValue(&fake_poll_var_);
232
233 bool value = false;
234 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
235 // Check that the scheduled callback isn't run until the timeout occurs.
236 RunGMainLoopMaxIterations(10);
237 EXPECT_FALSE(value);
238 RunGMainLoopUntil(10000, Bind(&GetBoolean, &value));
239 EXPECT_TRUE(value);
240}
241
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700242// Test that callback is called when evaluation context expires, and that it
Gilad Arnoldfd45a732014-08-07 15:53:46 -0700243// cannot be used again unless the expiration deadline is reset.
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700244TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutExpires) {
245 fake_async_var_.reset(new string("Async value"));
246 eval_ctx_->GetValue(&fake_async_var_);
247
248 bool value = false;
249 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
250 // Check that the scheduled callback isn't run until the timeout occurs.
251 RunGMainLoopMaxIterations(10);
252 EXPECT_FALSE(value);
253 RunGMainLoopUntil(10000, Bind(&GetBoolean, &value));
254 EXPECT_TRUE(value);
255
256 // Ensure that we cannot reschedule an evaluation.
257 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
Gilad Arnoldfd45a732014-08-07 15:53:46 -0700258
259 // Ensure that we can reschedule an evaluation after resetting expiration.
260 eval_ctx_->ResetExpiration();
261 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700262}
263
264// Test that we clear the events when destroying the EvaluationContext.
265TEST_F(UmEvaluationContextTest, RemoveObserversAndTimeoutTest) {
266 fake_async_var_.reset(new string("Async value"));
267 eval_ctx_->GetValue(&fake_async_var_);
268
269 bool value = false;
270 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
271 eval_ctx_ = nullptr;
272
273 // This should not trigger the callback since the EvaluationContext waiting
274 // for it is gone, and it should have remove all its observers.
275 fake_async_var_.NotifyValueChanged();
276 RunGMainLoopMaxIterations(100);
277 EXPECT_FALSE(value);
278}
279
Gilad Arnoldfb794f42014-07-01 15:36:31 -0700280// Scheduling two reevaluations from the callback should succeed.
281TEST_F(UmEvaluationContextTest,
282 RunOnValueChangeOrTimeoutReevaluatesRepeatedly) {
283 fake_poll_var_.reset(new string("Polled value"));
284 Closure evaluation = Bind(ReadVar<string>, eval_ctx_, &fake_poll_var_);
285 int num_reevaluations = 2;
286 bool done = false;
287
288 // Run the evaluation once.
289 evaluation.Run();
290
291 // Schedule repeated reevaluations.
292 Closure closure = Bind(EvaluateRepeatedly, evaluation, eval_ctx_,
293 &num_reevaluations, &done);
294 ASSERT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(closure));
295 RunGMainLoopUntil(10000, Bind(&GetBoolean, &done));
296 EXPECT_EQ(0, num_reevaluations);
297}
298
Alex Deymodb799532014-03-21 13:00:00 -0700299// Test that we can delete the EvaluationContext while having pending events.
Alex Deymo63784a52014-05-28 10:46:14 -0700300TEST_F(UmEvaluationContextTest, ObjectDeletedWithPendingEventsTest) {
Alex Deymodb799532014-03-21 13:00:00 -0700301 fake_async_var_.reset(new string("Async value"));
302 fake_poll_var_.reset(new string("Polled value"));
303 eval_ctx_->GetValue(&fake_async_var_);
304 eval_ctx_->GetValue(&fake_poll_var_);
305 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
306 // TearDown() checks for leaked observers on this async_variable, which means
307 // that our object is still alive after removing its reference.
308}
309
310// Test that timed events fired after removal of the EvaluationContext don't
311// crash.
Alex Deymo63784a52014-05-28 10:46:14 -0700312TEST_F(UmEvaluationContextTest, TimeoutEventAfterDeleteTest) {
Alex Deymodb799532014-03-21 13:00:00 -0700313 FakeVariable<string> fake_short_poll_var = {"fake_short_poll", TimeDelta()};
314 fake_short_poll_var.reset(new string("Polled value"));
315 eval_ctx_->GetValue(&fake_short_poll_var);
316 bool value = false;
317 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
318 // Remove the last reference to the EvaluationContext and run the loop for
319 // 1 second to give time to the main loop to trigger the timeout Event (of 0
320 // seconds). Our callback should not be called because the EvaluationContext
321 // was removed before the timeout event is attended.
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700322 eval_ctx_ = nullptr;
Alex Deymodb799532014-03-21 13:00:00 -0700323 RunGMainLoopUntil(1000, Bind(&GetBoolean, &value));
324 EXPECT_FALSE(value);
325}
326
Alex Deymo63784a52014-05-28 10:46:14 -0700327TEST_F(UmEvaluationContextTest, DefaultTimeout) {
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700328 // Test that the evaluation timeout calculation uses the default timeout on
329 // setup.
Alex Deymo41a75a72014-04-15 15:36:22 -0700330 EXPECT_CALL(mock_var_async_, GetValue(default_timeout_, _))
331 .WillOnce(Return(nullptr));
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700332 EXPECT_EQ(nullptr, eval_ctx_->GetValue(&mock_var_async_));
Alex Deymo41a75a72014-04-15 15:36:22 -0700333}
334
Alex Deymo63784a52014-05-28 10:46:14 -0700335TEST_F(UmEvaluationContextTest, TimeoutUpdatesWithMonotonicTime) {
Alex Deymo41a75a72014-04-15 15:36:22 -0700336 fake_clock_.SetMonotonicTime(
337 fake_clock_.GetMonotonicTime() + TimeDelta::FromSeconds(1));
338
339 TimeDelta timeout = default_timeout_ - TimeDelta::FromSeconds(1);
340
341 EXPECT_CALL(mock_var_async_, GetValue(timeout, _))
342 .WillOnce(Return(nullptr));
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700343 EXPECT_EQ(nullptr, eval_ctx_->GetValue(&mock_var_async_));
Alex Deymo41a75a72014-04-15 15:36:22 -0700344}
345
Gilad Arnolda65fced2014-07-23 09:01:31 -0700346TEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesWallclock) {
Alex Deymo41a75a72014-04-15 15:36:22 -0700347 base::Time cur_time = fake_clock_.GetWallclockTime();
348 // Advance the time on the clock but don't call ResetEvaluation yet.
349 fake_clock_.SetWallclockTime(cur_time + TimeDelta::FromSeconds(4));
350
Gilad Arnolda65fced2014-07-23 09:01:31 -0700351 EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
352 cur_time - TimeDelta::FromSeconds(1)));
353 EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
354 EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
355 cur_time + TimeDelta::FromSeconds(1)));
Alex Deymo41a75a72014-04-15 15:36:22 -0700356 // Call ResetEvaluation now, which should use the new evaluation time.
357 eval_ctx_->ResetEvaluation();
358
359 cur_time = fake_clock_.GetWallclockTime();
Gilad Arnolda65fced2014-07-23 09:01:31 -0700360 EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
361 cur_time - TimeDelta::FromSeconds(1)));
362 EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
363 EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
364 cur_time + TimeDelta::FromSeconds(1)));
Alex Deymo41a75a72014-04-15 15:36:22 -0700365}
366
Gilad Arnolda65fced2014-07-23 09:01:31 -0700367TEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesMonotonic) {
368 base::Time cur_time = fake_clock_.GetMonotonicTime();
369 // Advance the time on the clock but don't call ResetEvaluation yet.
370 fake_clock_.SetMonotonicTime(cur_time + TimeDelta::FromSeconds(4));
371
372 EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
373 cur_time - TimeDelta::FromSeconds(1)));
374 EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
375 EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
376 cur_time + TimeDelta::FromSeconds(1)));
377 // Call ResetEvaluation now, which should use the new evaluation time.
378 eval_ctx_->ResetEvaluation();
379
380 cur_time = fake_clock_.GetMonotonicTime();
381 EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
382 cur_time - TimeDelta::FromSeconds(1)));
383 EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
384 EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
385 cur_time + TimeDelta::FromSeconds(1)));
386}
387
388TEST_F(UmEvaluationContextTest,
389 IsWallclockTimeGreaterThanSignalsTriggerReevaluation) {
390 EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
Alex Deymo41a75a72014-04-15 15:36:22 -0700391 fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(1)));
392
Gilad Arnolda65fced2014-07-23 09:01:31 -0700393 // The "false" from IsWallclockTimeGreaterThan means that's not that timestamp
394 // yet, so this should schedule a callback for when that happens.
Alex Deymo41a75a72014-04-15 15:36:22 -0700395 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
396}
397
Gilad Arnolda65fced2014-07-23 09:01:31 -0700398TEST_F(UmEvaluationContextTest,
399 IsMonotonicTimeGreaterThanSignalsTriggerReevaluation) {
400 EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
401 fake_clock_.GetMonotonicTime() + TimeDelta::FromSeconds(1)));
402
403 // The "false" from IsMonotonicTimeGreaterThan means that's not that timestamp
404 // yet, so this should schedule a callback for when that happens.
405 EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
406}
407
408TEST_F(UmEvaluationContextTest,
409 IsWallclockTimeGreaterThanDoesntRecordPastTimestamps) {
410 // IsWallclockTimeGreaterThan() should ignore timestamps on the past for
411 // reevaluation.
412 EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
Alex Deymo41a75a72014-04-15 15:36:22 -0700413 fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(20)));
Gilad Arnolda65fced2014-07-23 09:01:31 -0700414 EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
Alex Deymo41a75a72014-04-15 15:36:22 -0700415 fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(1)));
416
417 // Callback should not be scheduled.
418 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
419}
420
Gilad Arnolda65fced2014-07-23 09:01:31 -0700421TEST_F(UmEvaluationContextTest,
422 IsMonotonicTimeGreaterThanDoesntRecordPastTimestamps) {
423 // IsMonotonicTimeGreaterThan() should ignore timestamps on the past for
424 // reevaluation.
425 EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
426 fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(20)));
427 EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
428 fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(1)));
429
430 // Callback should not be scheduled.
431 EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
432}
433
Alex Deymo63784a52014-05-28 10:46:14 -0700434TEST_F(UmEvaluationContextTest, DumpContext) {
David Zeuthenc1490282014-04-29 16:25:03 -0700435 // |fail_var_| yield "(no value)" since it is unset.
436 eval_ctx_->GetValue(&fail_var_);
437
438 // Check that this is included.
439 fake_int_var_.reset(new int(42));
440 eval_ctx_->GetValue(&fake_int_var_);
441
442 // Check that double-quotes are escaped properly.
443 fake_poll_var_.reset(new string("Hello \"world\"!"));
444 eval_ctx_->GetValue(&fake_poll_var_);
445
446 // Note that the variables are printed in alphabetical order. Also
Gilad Arnolda65fced2014-07-23 09:01:31 -0700447 // see UmEvaluationContextText::SetUp() where the values used for
448 // |evaluation_start_{monotonic,wallclock| are set.
David Zeuthenc1490282014-04-29 16:25:03 -0700449 EXPECT_EQ("{\n"
Gilad Arnolda65fced2014-07-23 09:01:31 -0700450 " \"evaluation_start_monotonic\": \"4/22/2009 19:25:00 GMT\",\n"
451 " \"evaluation_start_wallclock\": \"3/2/2006 1:23:45 GMT\",\n"
David Zeuthenc1490282014-04-29 16:25:03 -0700452 " \"variables\": {\n"
453 " \"fail_var\": \"(no value)\",\n"
454 " \"fake_int\": \"42\",\n"
455 " \"fake_poll\": \"Hello \\\"world\\\"!\"\n"
456 " }\n"
Gilad Arnold6e5ab5c2014-06-23 15:13:56 -0700457 "}",
David Zeuthenc1490282014-04-29 16:25:03 -0700458 eval_ctx_->DumpContext());
459}
460
Alex Deymo63784a52014-05-28 10:46:14 -0700461} // namespace chromeos_update_manager