1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
1623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
17aab50e31f0b80ed53a9b8d5dbabcf943974bd32cAlex Deymo#include "update_engine/update_manager/evaluation_context.h"
18aab50e31f0b80ed53a9b8d5dbabcf943974bd32cAlex Deymo
1902f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory>
2053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo#include <string>
2153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
2253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo#include <base/bind.h>
233f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/fake_message_loop.h>
243f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/message_loop_utils.h>
2523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo#include <gtest/gtest.h>
2623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
2739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/fake_clock.h"
2863784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/fake_variable.h"
2963784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/generic_variables.h"
3063784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/mock_variable.h"
3163784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/umtest_utils.h"
3223949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
3353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymousing base::Bind;
34fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnoldusing base::Closure;
3541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing base::Time;
3653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymousing base::TimeDelta;
373f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoop;
383f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoopRunMaxIterations;
393f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoopRunUntil;
4041a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing chromeos_update_engine::FakeClock;
4123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymousing std::string;
4202f7c1dee242f490143791dbb73fa23fa3007cfaBen Chanusing std::unique_ptr;
4341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing testing::Return;
4441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing testing::StrictMock;
4541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing testing::_;
4623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
47fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnoldnamespace chromeos_update_manager {
48fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
4953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymonamespace {
5053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
5153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymovoid DoNothing() {}
5253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
5353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo// Sets the value of the passed pointer to true.
5453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymovoid SetTrue(bool* value) {
5553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  *value = true;
5653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
5753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
5853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymobool GetBoolean(bool* value) {
5953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  return *value;
6053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
6153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
62fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnoldtemplate<typename T>
63fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnoldvoid ReadVar(scoped_refptr<EvaluationContext> ec, Variable<T>* var) {
64fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  ec->GetValue(var);
65fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold}
6653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
67fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold// Runs |evaluation|; if the value pointed by |count_p| is greater than zero,
68fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold// decrement it and schedule a reevaluation; otherwise, writes true to |done_p|.
69fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnoldvoid EvaluateRepeatedly(Closure evaluation, scoped_refptr<EvaluationContext> ec,
70fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold                        int* count_p, bool* done_p) {
71fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  evaluation.Run();
72fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
73fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  // Schedule reevaluation if needed.
74fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  if (*count_p > 0) {
75fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    Closure closure = Bind(EvaluateRepeatedly, evaluation, ec, count_p, done_p);
76fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    ASSERT_TRUE(ec->RunOnValueChangeOrTimeout(closure))
77fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold        << "Failed to schedule reevaluation, count_p=" << *count_p;
78fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    (*count_p)--;
79fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  } else {
80fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    *done_p = true;
81fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  }
82fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold}
83fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
84fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold}  // namespace
8523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
8663784a578dd26880454d70797519358a2326291bAlex Deymoclass UmEvaluationContextTest : public ::testing::Test {
8723949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo protected:
88610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void SetUp() override {
89509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo    loop_.SetAsCurrent();
90a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold    // Apr 22, 2009 19:25:00 UTC (this is a random reference point).
91a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold    fake_clock_.SetMonotonicTime(Time::FromTimeT(1240428300));
92a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold    // Mar 2, 2006 1:23:45 UTC.
93c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen    fake_clock_.SetWallclockTime(Time::FromTimeT(1141262625));
9483ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold    eval_ctx_ = new EvaluationContext(
9583ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold        &fake_clock_, default_timeout_, default_timeout_,
9602f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan        unique_ptr<base::Callback<void(EvaluationContext*)>>(nullptr));
9723949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  }
9823949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
99610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TearDown() override {
100fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    // Ensure that the evaluation context did not leak and is actually being
101fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    // destroyed.
102fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    if (eval_ctx_) {
103fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold      base::WeakPtr<EvaluationContext> eval_ctx_weak_alias =
104fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold          eval_ctx_->weak_ptr_factory_.GetWeakPtr();
10588b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko      ASSERT_NE(nullptr, eval_ctx_weak_alias.get());
106fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold      eval_ctx_ = nullptr;
10788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko      EXPECT_EQ(nullptr, eval_ctx_weak_alias.get())
108fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold          << "The evaluation context was not destroyed! This is likely a bug "
109fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold             "in how the test was written, look for leaking handles to the EC, "
110fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold             "possibly through closure objects.";
111fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    }
112fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
11353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo    // Check that the evaluation context removed all the observers.
11453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo    EXPECT_TRUE(fake_int_var_.observer_list_.empty());
11553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo    EXPECT_TRUE(fake_async_var_.observer_list_.empty());
11653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo    EXPECT_TRUE(fake_const_var_.observer_list_.empty());
11753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo    EXPECT_TRUE(fake_poll_var_.observer_list_.empty());
118509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo
119509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo    EXPECT_FALSE(loop_.PendingTasks());
12053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  }
12153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
122f329b933db41d26644a97afef928eb1b319d6d99Alex Deymo  TimeDelta default_timeout_ = TimeDelta::FromSeconds(5);
12341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
1243f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::FakeMessageLoop loop_{nullptr};
12541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  FakeClock fake_clock_;
1267b948f060281eb1f9ab198bce67da5aadf03df60Alex Deymo  scoped_refptr<EvaluationContext> eval_ctx_;
12753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
12853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // FakeVariables used for testing the EvaluationContext. These are required
12953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // here to prevent them from going away *before* the EvaluationContext under
13053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // test does, which keeps a reference to them.
131c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  FakeVariable<bool> fail_var_ = {"fail_var", kVariableModePoll};
13253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  FakeVariable<int> fake_int_var_ = {"fake_int", kVariableModePoll};
13353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  FakeVariable<string> fake_async_var_ = {"fake_async", kVariableModeAsync};
13453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  FakeVariable<string> fake_const_var_ = {"fake_const", kVariableModeConst};
13553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  FakeVariable<string> fake_poll_var_ = {"fake_poll",
13653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo                                         TimeDelta::FromSeconds(1)};
137fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  StrictMock<MockVariable<string>> mock_var_async_ {
138fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    "mock_var_async", kVariableModeAsync};
139fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  StrictMock<MockVariable<string>> mock_var_poll_ {
140fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold    "mock_var_poll", kVariableModePoll};
14123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo};
14223949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
14363784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, GetValueFails) {
14488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  // FakeVariable is initialized as returning null.
14588b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  EXPECT_EQ(nullptr, eval_ctx_->GetValue(&fake_int_var_));
14623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo}
14723949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
14863784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, GetValueFailsWithInvalidVar) {
14988b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  EXPECT_EQ(nullptr, eval_ctx_->GetValue(static_cast<Variable<int>*>(nullptr)));
15023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo}
15123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
15263784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, GetValueReturns) {
15323949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  const int* p_fake_int;
15423949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
15523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  fake_int_var_.reset(new int(42));
15623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
15788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  ASSERT_NE(nullptr, p_fake_int);
15823949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  EXPECT_EQ(42, *p_fake_int);
15923949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo}
16023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
16163784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, GetValueCached) {
16223949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  const int* p_fake_int;
16323949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
16423949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  fake_int_var_.reset(new int(42));
16523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
16623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
16723949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  // Check that if the variable changes, the EvaluationContext keeps returning
16823949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  // the cached value.
16923949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  fake_int_var_.reset(new int(5));
17023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
17123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
17288b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  ASSERT_NE(nullptr, p_fake_int);
17323949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  EXPECT_EQ(42, *p_fake_int);
17423949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo}
17523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
17663784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, GetValueCachesNull) {
17723949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  const int* p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
17888b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  EXPECT_EQ(nullptr, p_fake_int);
17923949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
18023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  fake_int_var_.reset(new int(42));
181cc0e5cf2bc2c480196692b76d8ce5c4268de8e72Alex Deymo  // A second attempt to read the variable should not work because this
18288b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  // EvaluationContext already got a null value.
18323949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
18488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  EXPECT_EQ(nullptr, p_fake_int);
18523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo}
18623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
18763784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, GetValueMixedTypes) {
18823949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  const int* p_fake_int;
18923949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  const string* p_fake_string;
19023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
19123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  fake_int_var_.reset(new int(42));
19253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  fake_poll_var_.reset(new string("Hello world!"));
19323949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  // Check that the EvaluationContext can handle multiple Variable types. This
19423949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  // is mostly a compile-time check due to the template nature of this method.
19523949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
19653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  p_fake_string = eval_ctx_->GetValue(&fake_poll_var_);
19723949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
19888b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  ASSERT_NE(nullptr, p_fake_int);
19923949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  EXPECT_EQ(42, *p_fake_int);
20023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
20188b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  ASSERT_NE(nullptr, p_fake_string);
20223949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo  EXPECT_EQ("Hello world!", *p_fake_string);
20323949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo}
20423949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo
20553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo// Test that we don't schedule an event if there's no variable to wait for.
206f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutWithoutVariables) {
20753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  fake_const_var_.reset(new string("Hello world!"));
20853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_EQ(*eval_ctx_->GetValue(&fake_const_var_), "Hello world!");
20953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
21053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
21153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
21253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
213fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold// Test that reevaluation occurs when an async variable it depends on changes.
214f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutWithVariables) {
21553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  fake_async_var_.reset(new string("Async value"));
21653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  eval_ctx_->GetValue(&fake_async_var_);
21753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
21853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  bool value = false;
21953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
22053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // Check that the scheduled callback isn't run until we signal a ValueChaged.
221509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunMaxIterations(MessageLoop::current(), 100);
22253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_FALSE(value);
22353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
22453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  fake_async_var_.NotifyValueChanged();
22553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_FALSE(value);
22653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // Ensure that the scheduled callback isn't run until we are back on the main
22753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // loop.
228509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunMaxIterations(MessageLoop::current(), 100);
22953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(value);
23053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
23153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
23253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo// Test that we don't re-schedule the events if we are attending one.
233f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutCalledTwice) {
23453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  fake_async_var_.reset(new string("Async value"));
23553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  eval_ctx_->GetValue(&fake_async_var_);
23653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
23753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  bool value = false;
23853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
23953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
24053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
24153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // The scheduled event should still work.
24253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  fake_async_var_.NotifyValueChanged();
243509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunMaxIterations(MessageLoop::current(), 100);
24453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(value);
24553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
24653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
247f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold// Test that reevaluation occurs when a polling timeout fires.
248f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutRunsFromTimeout) {
249f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  fake_poll_var_.reset(new string("Polled value"));
250f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  eval_ctx_->GetValue(&fake_poll_var_);
25153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
25253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  bool value = false;
25353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
254f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  // Check that the scheduled callback isn't run until the timeout occurs.
255509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
25653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_FALSE(value);
257509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunUntil(MessageLoop::current(),
258509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      TimeDelta::FromSeconds(10),
259509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      Bind(&GetBoolean, &value));
260f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  EXPECT_TRUE(value);
26153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
26253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
263f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold// Test that callback is called when evaluation context expires, and that it
264fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold// cannot be used again unless the expiration deadline is reset.
265f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutExpires) {
266f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  fake_async_var_.reset(new string("Async value"));
267f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  eval_ctx_->GetValue(&fake_async_var_);
26853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
26953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  bool value = false;
27053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
27153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  // Check that the scheduled callback isn't run until the timeout occurs.
272509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunMaxIterations(MessageLoop::current(), 10);
27353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_FALSE(value);
274509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunUntil(MessageLoop::current(),
275509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      TimeDelta::FromSeconds(10),
276509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      Bind(&GetBoolean, &value));
27753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo  EXPECT_TRUE(value);
278f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold
279f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  // Ensure that we cannot reschedule an evaluation.
280f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
281fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold
282fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold  // Ensure that we can reschedule an evaluation after resetting expiration.
283fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold  eval_ctx_->ResetExpiration();
284fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
285f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold}
286f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold
287f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold// Test that we clear the events when destroying the EvaluationContext.
288f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTEST_F(UmEvaluationContextTest, RemoveObserversAndTimeoutTest) {
289f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  fake_async_var_.reset(new string("Async value"));
290f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  eval_ctx_->GetValue(&fake_async_var_);
291f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold
292f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  bool value = false;
293f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
294f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  eval_ctx_ = nullptr;
295f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold
296f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  // This should not trigger the callback since the EvaluationContext waiting
297f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  // for it is gone, and it should have remove all its observers.
298f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  fake_async_var_.NotifyValueChanged();
299509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunMaxIterations(MessageLoop::current(), 100);
300f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  EXPECT_FALSE(value);
30153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo}
30253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo
303fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold// Scheduling two reevaluations from the callback should succeed.
304fb794f4b7274576e10b0df291655ad6c88a97df4Gilad ArnoldTEST_F(UmEvaluationContextTest,
305fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold       RunOnValueChangeOrTimeoutReevaluatesRepeatedly) {
306fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  fake_poll_var_.reset(new string("Polled value"));
307fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  Closure evaluation = Bind(ReadVar<string>, eval_ctx_, &fake_poll_var_);
308fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  int num_reevaluations = 2;
309fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  bool done = false;
310fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
311fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  // Run the evaluation once.
312fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  evaluation.Run();
313fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
314fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  // Schedule repeated reevaluations.
315fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  Closure closure = Bind(EvaluateRepeatedly, evaluation, eval_ctx_,
316fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold                         &num_reevaluations, &done);
317fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  ASSERT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(closure));
318509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunUntil(MessageLoop::current(),
319509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      TimeDelta::FromSeconds(10),
320509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      Bind(&GetBoolean, &done));
321fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold  EXPECT_EQ(0, num_reevaluations);
322fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold}
323fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold
324db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo// Test that we can delete the EvaluationContext while having pending events.
32563784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, ObjectDeletedWithPendingEventsTest) {
326db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  fake_async_var_.reset(new string("Async value"));
327db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  fake_poll_var_.reset(new string("Polled value"));
328db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  eval_ctx_->GetValue(&fake_async_var_);
329db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  eval_ctx_->GetValue(&fake_poll_var_);
330db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
331db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  // TearDown() checks for leaked observers on this async_variable, which means
332db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  // that our object is still alive after removing its reference.
333db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo}
334db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo
335db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo// Test that timed events fired after removal of the EvaluationContext don't
336db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo// crash.
33763784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, TimeoutEventAfterDeleteTest) {
3380bb234147ea8f0247b733375fcf1685eaf329aacAlex Deymo  FakeVariable<string> fake_short_poll_var = {"fake_short_poll",
3390bb234147ea8f0247b733375fcf1685eaf329aacAlex Deymo                                              TimeDelta::FromSeconds(1)};
340db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  fake_short_poll_var.reset(new string("Polled value"));
341db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  eval_ctx_->GetValue(&fake_short_poll_var);
342db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  bool value = false;
343db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
344db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  // Remove the last reference to the EvaluationContext and run the loop for
3450bb234147ea8f0247b733375fcf1685eaf329aacAlex Deymo  // 10 seconds to give time to the main loop to trigger the timeout Event (of 1
3460bb234147ea8f0247b733375fcf1685eaf329aacAlex Deymo  // second). Our callback should not be called because the EvaluationContext
347db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  // was removed before the timeout event is attended.
348f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  eval_ctx_ = nullptr;
349509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo  MessageLoopRunUntil(MessageLoop::current(),
350509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      TimeDelta::FromSeconds(10),
351509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo                      Bind(&GetBoolean, &value));
352db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo  EXPECT_FALSE(value);
353db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo}
354db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo
35563784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, DefaultTimeout) {
356f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  // Test that the evaluation timeout calculation uses the default timeout on
357f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold  // setup.
35841a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  EXPECT_CALL(mock_var_async_, GetValue(default_timeout_, _))
35941a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo      .WillOnce(Return(nullptr));
36088b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  EXPECT_EQ(nullptr, eval_ctx_->GetValue(&mock_var_async_));
36141a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo}
36241a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
36363784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, TimeoutUpdatesWithMonotonicTime) {
36441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  fake_clock_.SetMonotonicTime(
36541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo      fake_clock_.GetMonotonicTime() + TimeDelta::FromSeconds(1));
36641a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
36741a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  TimeDelta timeout = default_timeout_ - TimeDelta::FromSeconds(1);
36841a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
36941a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  EXPECT_CALL(mock_var_async_, GetValue(timeout, _))
37041a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo      .WillOnce(Return(nullptr));
37188b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko  EXPECT_EQ(nullptr, eval_ctx_->GetValue(&mock_var_async_));
37241a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo}
37341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
374a65fced5f4c2b551616b26ee90a800b44090735fGilad ArnoldTEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesWallclock) {
375f329b933db41d26644a97afef928eb1b319d6d99Alex Deymo  Time cur_time = fake_clock_.GetWallclockTime();
37641a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  // Advance the time on the clock but don't call ResetEvaluation yet.
37741a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  fake_clock_.SetWallclockTime(cur_time + TimeDelta::FromSeconds(4));
37841a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
379a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
380a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time - TimeDelta::FromSeconds(1)));
381a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
382a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
383a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time + TimeDelta::FromSeconds(1)));
38441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  // Call ResetEvaluation now, which should use the new evaluation time.
38541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  eval_ctx_->ResetEvaluation();
38641a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
38741a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  cur_time = fake_clock_.GetWallclockTime();
388a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
389a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time - TimeDelta::FromSeconds(1)));
390a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
391a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
392a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time + TimeDelta::FromSeconds(1)));
39341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo}
39441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
395a65fced5f4c2b551616b26ee90a800b44090735fGilad ArnoldTEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesMonotonic) {
396f329b933db41d26644a97afef928eb1b319d6d99Alex Deymo  Time cur_time = fake_clock_.GetMonotonicTime();
397a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // Advance the time on the clock but don't call ResetEvaluation yet.
398a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  fake_clock_.SetMonotonicTime(cur_time + TimeDelta::FromSeconds(4));
399a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
400a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
401a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time - TimeDelta::FromSeconds(1)));
402a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
403a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
404a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time + TimeDelta::FromSeconds(1)));
405a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // Call ResetEvaluation now, which should use the new evaluation time.
406a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  eval_ctx_->ResetEvaluation();
407a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
408a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  cur_time = fake_clock_.GetMonotonicTime();
409a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
410a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time - TimeDelta::FromSeconds(1)));
411a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
412a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
413a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold          cur_time + TimeDelta::FromSeconds(1)));
414a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold}
415a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
416a65fced5f4c2b551616b26ee90a800b44090735fGilad ArnoldTEST_F(UmEvaluationContextTest,
417a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold       IsWallclockTimeGreaterThanSignalsTriggerReevaluation) {
418a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
41941a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo      fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(1)));
42041a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
421a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // The "false" from IsWallclockTimeGreaterThan means that's not that timestamp
422a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // yet, so this should schedule a callback for when that happens.
423a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
424a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold}
425a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
426a65fced5f4c2b551616b26ee90a800b44090735fGilad ArnoldTEST_F(UmEvaluationContextTest,
427a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold       IsMonotonicTimeGreaterThanSignalsTriggerReevaluation) {
428a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
429a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold      fake_clock_.GetMonotonicTime() + TimeDelta::FromSeconds(1)));
430a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
431a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // The "false" from IsMonotonicTimeGreaterThan means that's not that timestamp
432a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // yet, so this should schedule a callback for when that happens.
43341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
43441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo}
43541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
436a65fced5f4c2b551616b26ee90a800b44090735fGilad ArnoldTEST_F(UmEvaluationContextTest,
437a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold       IsWallclockTimeGreaterThanDoesntRecordPastTimestamps) {
438a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // IsWallclockTimeGreaterThan() should ignore timestamps on the past for
439a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // reevaluation.
440a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
44141a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo      fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(20)));
442a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
44341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo      fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(1)));
44441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
44541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  // Callback should not be scheduled.
44641a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo  EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
44741a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo}
44841a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo
449a65fced5f4c2b551616b26ee90a800b44090735fGilad ArnoldTEST_F(UmEvaluationContextTest,
450a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold       IsMonotonicTimeGreaterThanDoesntRecordPastTimestamps) {
451a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // IsMonotonicTimeGreaterThan() should ignore timestamps on the past for
452a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // reevaluation.
453a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
454a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold      fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(20)));
455a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
456a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold      fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(1)));
457a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
458a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // Callback should not be scheduled.
459a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&DoNothing)));
460a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold}
461a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold
46263784a578dd26880454d70797519358a2326291bAlex DeymoTEST_F(UmEvaluationContextTest, DumpContext) {
463c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  // |fail_var_| yield "(no value)" since it is unset.
464c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  eval_ctx_->GetValue(&fail_var_);
465c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen
466c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  // Check that this is included.
467c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  fake_int_var_.reset(new int(42));
468c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  eval_ctx_->GetValue(&fake_int_var_);
469c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen
470c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  // Check that double-quotes are escaped properly.
471c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  fake_poll_var_.reset(new string("Hello \"world\"!"));
472c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  eval_ctx_->GetValue(&fake_poll_var_);
473c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen
474c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  // Note that the variables are printed in alphabetical order. Also
475a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // see UmEvaluationContextText::SetUp() where the values used for
476a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold  // |evaluation_start_{monotonic,wallclock| are set.
477c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen  EXPECT_EQ("{\n"
478a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold            "   \"evaluation_start_monotonic\": \"4/22/2009 19:25:00 GMT\",\n"
479a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold            "   \"evaluation_start_wallclock\": \"3/2/2006 1:23:45 GMT\",\n"
480c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen            "   \"variables\": {\n"
481c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen            "      \"fail_var\": \"(no value)\",\n"
482c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen            "      \"fake_int\": \"42\",\n"
483c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen            "      \"fake_poll\": \"Hello \\\"world\\\"!\"\n"
484c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen            "   }\n"
4856e5ab5c011a214aa345ecbba3d910c2ffaec3c83Gilad Arnold            "}",
486c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen            eval_ctx_->DumpContext());
487c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen}
488c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen
48963784a578dd26880454d70797519358a2326291bAlex Deymo}  // namespace chromeos_update_manager
490