evaluation_context_unittest.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. //
  2. // Copyright (C) 2014 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #include "update_engine/update_manager/evaluation_context.h"
  17. #include <memory>
  18. #include <string>
  19. #include <base/bind.h>
  20. #include <base/bind_helpers.h>
  21. #include <brillo/message_loops/fake_message_loop.h>
  22. #include <brillo/message_loops/message_loop_utils.h>
  23. #include <gtest/gtest.h>
  24. #include "update_engine/common/fake_clock.h"
  25. #include "update_engine/update_manager/fake_variable.h"
  26. #include "update_engine/update_manager/generic_variables.h"
  27. #include "update_engine/update_manager/mock_variable.h"
  28. #include "update_engine/update_manager/umtest_utils.h"
  29. using base::Bind;
  30. using base::Closure;
  31. using base::Time;
  32. using base::TimeDelta;
  33. using brillo::MessageLoop;
  34. using brillo::MessageLoopRunMaxIterations;
  35. using brillo::MessageLoopRunUntil;
  36. using chromeos_update_engine::FakeClock;
  37. using std::string;
  38. using std::unique_ptr;
  39. using testing::_;
  40. using testing::Return;
  41. using testing::StrictMock;
  42. namespace chromeos_update_manager {
  43. namespace {
  44. // Sets the value of the passed pointer to true.
  45. void SetTrue(bool* value) {
  46. *value = true;
  47. }
  48. bool GetBoolean(bool* value) {
  49. return *value;
  50. }
  51. template <typename T>
  52. void ReadVar(scoped_refptr<EvaluationContext> ec, Variable<T>* var) {
  53. ec->GetValue(var);
  54. }
  55. // Runs |evaluation|; if the value pointed by |count_p| is greater than zero,
  56. // decrement it and schedule a reevaluation; otherwise, writes true to |done_p|.
  57. void EvaluateRepeatedly(Closure evaluation,
  58. scoped_refptr<EvaluationContext> ec,
  59. int* count_p,
  60. bool* done_p) {
  61. evaluation.Run();
  62. // Schedule reevaluation if needed.
  63. if (*count_p > 0) {
  64. Closure closure = Bind(EvaluateRepeatedly, evaluation, ec, count_p, done_p);
  65. ASSERT_TRUE(ec->RunOnValueChangeOrTimeout(closure))
  66. << "Failed to schedule reevaluation, count_p=" << *count_p;
  67. (*count_p)--;
  68. } else {
  69. *done_p = true;
  70. }
  71. }
  72. } // namespace
  73. class UmEvaluationContextTest : public ::testing::Test {
  74. protected:
  75. void SetUp() override {
  76. loop_.SetAsCurrent();
  77. // Apr 22, 2009 19:25:00 UTC (this is a random reference point).
  78. fake_clock_.SetMonotonicTime(Time::FromTimeT(1240428300));
  79. // Mar 2, 2006 1:23:45 UTC.
  80. fake_clock_.SetWallclockTime(Time::FromTimeT(1141262625));
  81. eval_ctx_ = new EvaluationContext(
  82. &fake_clock_,
  83. default_timeout_,
  84. default_timeout_,
  85. unique_ptr<base::Callback<void(EvaluationContext*)>>(nullptr));
  86. }
  87. void TearDown() override {
  88. // Ensure that the evaluation context did not leak and is actually being
  89. // destroyed.
  90. if (eval_ctx_) {
  91. base::WeakPtr<EvaluationContext> eval_ctx_weak_alias =
  92. eval_ctx_->weak_ptr_factory_.GetWeakPtr();
  93. ASSERT_NE(nullptr, eval_ctx_weak_alias.get());
  94. eval_ctx_ = nullptr;
  95. EXPECT_EQ(nullptr, eval_ctx_weak_alias.get())
  96. << "The evaluation context was not destroyed! This is likely a bug "
  97. "in how the test was written, look for leaking handles to the EC, "
  98. "possibly through closure objects.";
  99. }
  100. // Check that the evaluation context removed all the observers.
  101. EXPECT_TRUE(fake_int_var_.observer_list_.empty());
  102. EXPECT_TRUE(fake_async_var_.observer_list_.empty());
  103. EXPECT_TRUE(fake_const_var_.observer_list_.empty());
  104. EXPECT_TRUE(fake_poll_var_.observer_list_.empty());
  105. EXPECT_FALSE(loop_.PendingTasks());
  106. }
  107. TimeDelta default_timeout_ = TimeDelta::FromSeconds(5);
  108. brillo::FakeMessageLoop loop_{nullptr};
  109. FakeClock fake_clock_;
  110. scoped_refptr<EvaluationContext> eval_ctx_;
  111. // FakeVariables used for testing the EvaluationContext. These are required
  112. // here to prevent them from going away *before* the EvaluationContext under
  113. // test does, which keeps a reference to them.
  114. FakeVariable<bool> fail_var_ = {"fail_var", kVariableModePoll};
  115. FakeVariable<int> fake_int_var_ = {"fake_int", kVariableModePoll};
  116. FakeVariable<string> fake_async_var_ = {"fake_async", kVariableModeAsync};
  117. FakeVariable<string> fake_const_var_ = {"fake_const", kVariableModeConst};
  118. FakeVariable<string> fake_poll_var_ = {"fake_poll",
  119. TimeDelta::FromSeconds(1)};
  120. StrictMock<MockVariable<string>> mock_var_async_{"mock_var_async",
  121. kVariableModeAsync};
  122. StrictMock<MockVariable<string>> mock_var_poll_{"mock_var_poll",
  123. kVariableModePoll};
  124. };
  125. TEST_F(UmEvaluationContextTest, GetValueFails) {
  126. // FakeVariable is initialized as returning null.
  127. EXPECT_EQ(nullptr, eval_ctx_->GetValue(&fake_int_var_));
  128. }
  129. TEST_F(UmEvaluationContextTest, GetValueFailsWithInvalidVar) {
  130. EXPECT_EQ(nullptr, eval_ctx_->GetValue(static_cast<Variable<int>*>(nullptr)));
  131. }
  132. TEST_F(UmEvaluationContextTest, GetValueReturns) {
  133. const int* p_fake_int;
  134. fake_int_var_.reset(new int(42));
  135. p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
  136. ASSERT_NE(nullptr, p_fake_int);
  137. EXPECT_EQ(42, *p_fake_int);
  138. }
  139. TEST_F(UmEvaluationContextTest, GetValueCached) {
  140. const int* p_fake_int;
  141. fake_int_var_.reset(new int(42));
  142. p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
  143. // Check that if the variable changes, the EvaluationContext keeps returning
  144. // the cached value.
  145. fake_int_var_.reset(new int(5));
  146. p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
  147. ASSERT_NE(nullptr, p_fake_int);
  148. EXPECT_EQ(42, *p_fake_int);
  149. }
  150. TEST_F(UmEvaluationContextTest, GetValueCachesNull) {
  151. const int* p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
  152. EXPECT_EQ(nullptr, p_fake_int);
  153. fake_int_var_.reset(new int(42));
  154. // A second attempt to read the variable should not work because this
  155. // EvaluationContext already got a null value.
  156. p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
  157. EXPECT_EQ(nullptr, p_fake_int);
  158. }
  159. TEST_F(UmEvaluationContextTest, GetValueMixedTypes) {
  160. const int* p_fake_int;
  161. const string* p_fake_string;
  162. fake_int_var_.reset(new int(42));
  163. fake_poll_var_.reset(new string("Hello world!"));
  164. // Check that the EvaluationContext can handle multiple Variable types. This
  165. // is mostly a compile-time check due to the template nature of this method.
  166. p_fake_int = eval_ctx_->GetValue(&fake_int_var_);
  167. p_fake_string = eval_ctx_->GetValue(&fake_poll_var_);
  168. ASSERT_NE(nullptr, p_fake_int);
  169. EXPECT_EQ(42, *p_fake_int);
  170. ASSERT_NE(nullptr, p_fake_string);
  171. EXPECT_EQ("Hello world!", *p_fake_string);
  172. }
  173. // Test that we don't schedule an event if there's no variable to wait for.
  174. TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutWithoutVariables) {
  175. fake_const_var_.reset(new string("Hello world!"));
  176. EXPECT_EQ(*eval_ctx_->GetValue(&fake_const_var_), "Hello world!");
  177. EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(
  178. #if BASE_VER < 576279
  179. Bind(&base::DoNothing)
  180. #else
  181. base::DoNothing()
  182. #endif
  183. ));
  184. }
  185. // Test that reevaluation occurs when an async variable it depends on changes.
  186. TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutWithVariables) {
  187. fake_async_var_.reset(new string("Async value"));
  188. eval_ctx_->GetValue(&fake_async_var_);
  189. bool value = false;
  190. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  191. // Check that the scheduled callback isn't run until we signal a ValueChaged.
  192. MessageLoopRunMaxIterations(MessageLoop::current(), 100);
  193. EXPECT_FALSE(value);
  194. fake_async_var_.NotifyValueChanged();
  195. EXPECT_FALSE(value);
  196. // Ensure that the scheduled callback isn't run until we are back on the main
  197. // loop.
  198. MessageLoopRunMaxIterations(MessageLoop::current(), 100);
  199. EXPECT_TRUE(value);
  200. }
  201. // Test that we don't re-schedule the events if we are attending one.
  202. TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutCalledTwice) {
  203. fake_async_var_.reset(new string("Async value"));
  204. eval_ctx_->GetValue(&fake_async_var_);
  205. bool value = false;
  206. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  207. EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  208. // The scheduled event should still work.
  209. fake_async_var_.NotifyValueChanged();
  210. MessageLoopRunMaxIterations(MessageLoop::current(), 100);
  211. EXPECT_TRUE(value);
  212. }
  213. // Test that reevaluation occurs when a polling timeout fires.
  214. TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutRunsFromTimeout) {
  215. fake_poll_var_.reset(new string("Polled value"));
  216. eval_ctx_->GetValue(&fake_poll_var_);
  217. bool value = false;
  218. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  219. // Check that the scheduled callback isn't run until the timeout occurs.
  220. MessageLoopRunMaxIterations(MessageLoop::current(), 10);
  221. EXPECT_FALSE(value);
  222. MessageLoopRunUntil(MessageLoop::current(),
  223. TimeDelta::FromSeconds(10),
  224. Bind(&GetBoolean, &value));
  225. EXPECT_TRUE(value);
  226. }
  227. // Test that callback is called when evaluation context expires, and that it
  228. // cannot be used again unless the expiration deadline is reset.
  229. TEST_F(UmEvaluationContextTest, RunOnValueChangeOrTimeoutExpires) {
  230. fake_async_var_.reset(new string("Async value"));
  231. eval_ctx_->GetValue(&fake_async_var_);
  232. bool value = false;
  233. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  234. // Check that the scheduled callback isn't run until the timeout occurs.
  235. MessageLoopRunMaxIterations(MessageLoop::current(), 10);
  236. EXPECT_FALSE(value);
  237. MessageLoopRunUntil(MessageLoop::current(),
  238. TimeDelta::FromSeconds(10),
  239. Bind(&GetBoolean, &value));
  240. EXPECT_TRUE(value);
  241. // Ensure that we cannot reschedule an evaluation.
  242. EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(
  243. #if BASE_VER < 576279
  244. Bind(&base::DoNothing)
  245. #else
  246. base::DoNothing()
  247. #endif
  248. ));
  249. // Ensure that we can reschedule an evaluation after resetting expiration.
  250. eval_ctx_->ResetExpiration();
  251. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(
  252. #if BASE_VER < 576279
  253. Bind(&base::DoNothing)
  254. #else
  255. base::DoNothing()
  256. #endif
  257. ));
  258. }
  259. // Test that we clear the events when destroying the EvaluationContext.
  260. TEST_F(UmEvaluationContextTest, RemoveObserversAndTimeoutTest) {
  261. fake_async_var_.reset(new string("Async value"));
  262. eval_ctx_->GetValue(&fake_async_var_);
  263. bool value = false;
  264. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  265. eval_ctx_ = nullptr;
  266. // This should not trigger the callback since the EvaluationContext waiting
  267. // for it is gone, and it should have remove all its observers.
  268. fake_async_var_.NotifyValueChanged();
  269. MessageLoopRunMaxIterations(MessageLoop::current(), 100);
  270. EXPECT_FALSE(value);
  271. }
  272. // Scheduling two reevaluations from the callback should succeed.
  273. TEST_F(UmEvaluationContextTest,
  274. RunOnValueChangeOrTimeoutReevaluatesRepeatedly) {
  275. fake_poll_var_.reset(new string("Polled value"));
  276. Closure evaluation = Bind(ReadVar<string>, eval_ctx_, &fake_poll_var_);
  277. int num_reevaluations = 2;
  278. bool done = false;
  279. // Run the evaluation once.
  280. evaluation.Run();
  281. // Schedule repeated reevaluations.
  282. Closure closure = Bind(
  283. EvaluateRepeatedly, evaluation, eval_ctx_, &num_reevaluations, &done);
  284. ASSERT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(closure));
  285. MessageLoopRunUntil(MessageLoop::current(),
  286. TimeDelta::FromSeconds(10),
  287. Bind(&GetBoolean, &done));
  288. EXPECT_EQ(0, num_reevaluations);
  289. }
  290. // Test that we can delete the EvaluationContext while having pending events.
  291. TEST_F(UmEvaluationContextTest, ObjectDeletedWithPendingEventsTest) {
  292. fake_async_var_.reset(new string("Async value"));
  293. fake_poll_var_.reset(new string("Polled value"));
  294. eval_ctx_->GetValue(&fake_async_var_);
  295. eval_ctx_->GetValue(&fake_poll_var_);
  296. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(
  297. #if BASE_VER < 576279
  298. Bind(&base::DoNothing)
  299. #else
  300. base::DoNothing()
  301. #endif
  302. ));
  303. // TearDown() checks for leaked observers on this async_variable, which means
  304. // that our object is still alive after removing its reference.
  305. }
  306. // Test that timed events fired after removal of the EvaluationContext don't
  307. // crash.
  308. TEST_F(UmEvaluationContextTest, TimeoutEventAfterDeleteTest) {
  309. FakeVariable<string> fake_short_poll_var = {"fake_short_poll",
  310. TimeDelta::FromSeconds(1)};
  311. fake_short_poll_var.reset(new string("Polled value"));
  312. eval_ctx_->GetValue(&fake_short_poll_var);
  313. bool value = false;
  314. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(Bind(&SetTrue, &value)));
  315. // Remove the last reference to the EvaluationContext and run the loop for
  316. // 10 seconds to give time to the main loop to trigger the timeout Event (of 1
  317. // second). Our callback should not be called because the EvaluationContext
  318. // was removed before the timeout event is attended.
  319. eval_ctx_ = nullptr;
  320. MessageLoopRunUntil(MessageLoop::current(),
  321. TimeDelta::FromSeconds(10),
  322. Bind(&GetBoolean, &value));
  323. EXPECT_FALSE(value);
  324. }
  325. TEST_F(UmEvaluationContextTest, DefaultTimeout) {
  326. // Test that the evaluation timeout calculation uses the default timeout on
  327. // setup.
  328. EXPECT_CALL(mock_var_async_, GetValue(default_timeout_, _))
  329. .WillOnce(Return(nullptr));
  330. EXPECT_EQ(nullptr, eval_ctx_->GetValue(&mock_var_async_));
  331. }
  332. TEST_F(UmEvaluationContextTest, TimeoutUpdatesWithMonotonicTime) {
  333. fake_clock_.SetMonotonicTime(fake_clock_.GetMonotonicTime() +
  334. TimeDelta::FromSeconds(1));
  335. TimeDelta timeout = default_timeout_ - TimeDelta::FromSeconds(1);
  336. EXPECT_CALL(mock_var_async_, GetValue(timeout, _)).WillOnce(Return(nullptr));
  337. EXPECT_EQ(nullptr, eval_ctx_->GetValue(&mock_var_async_));
  338. }
  339. TEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesWallclock) {
  340. Time cur_time = fake_clock_.GetWallclockTime();
  341. // Advance the time on the clock but don't call ResetEvaluation yet.
  342. fake_clock_.SetWallclockTime(cur_time + TimeDelta::FromSeconds(4));
  343. EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time -
  344. TimeDelta::FromSeconds(1)));
  345. EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
  346. EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
  347. cur_time + TimeDelta::FromSeconds(1)));
  348. // Call ResetEvaluation now, which should use the new evaluation time.
  349. eval_ctx_->ResetEvaluation();
  350. cur_time = fake_clock_.GetWallclockTime();
  351. EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time -
  352. TimeDelta::FromSeconds(1)));
  353. EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(cur_time));
  354. EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
  355. cur_time + TimeDelta::FromSeconds(1)));
  356. }
  357. TEST_F(UmEvaluationContextTest, ResetEvaluationResetsTimesMonotonic) {
  358. Time cur_time = fake_clock_.GetMonotonicTime();
  359. // Advance the time on the clock but don't call ResetEvaluation yet.
  360. fake_clock_.SetMonotonicTime(cur_time + TimeDelta::FromSeconds(4));
  361. EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time -
  362. TimeDelta::FromSeconds(1)));
  363. EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
  364. EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
  365. cur_time + TimeDelta::FromSeconds(1)));
  366. // Call ResetEvaluation now, which should use the new evaluation time.
  367. eval_ctx_->ResetEvaluation();
  368. cur_time = fake_clock_.GetMonotonicTime();
  369. EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time -
  370. TimeDelta::FromSeconds(1)));
  371. EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(cur_time));
  372. EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
  373. cur_time + TimeDelta::FromSeconds(1)));
  374. }
  375. TEST_F(UmEvaluationContextTest,
  376. IsWallclockTimeGreaterThanSignalsTriggerReevaluation) {
  377. EXPECT_FALSE(eval_ctx_->IsWallclockTimeGreaterThan(
  378. fake_clock_.GetWallclockTime() + TimeDelta::FromSeconds(1)));
  379. // The "false" from IsWallclockTimeGreaterThan means that's not that timestamp
  380. // yet, so this should schedule a callback for when that happens.
  381. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(
  382. #if BASE_VER < 576279
  383. Bind(&base::DoNothing)
  384. #else
  385. base::DoNothing()
  386. #endif
  387. ));
  388. }
  389. TEST_F(UmEvaluationContextTest,
  390. IsMonotonicTimeGreaterThanSignalsTriggerReevaluation) {
  391. EXPECT_FALSE(eval_ctx_->IsMonotonicTimeGreaterThan(
  392. fake_clock_.GetMonotonicTime() + TimeDelta::FromSeconds(1)));
  393. // The "false" from IsMonotonicTimeGreaterThan means that's not that timestamp
  394. // yet, so this should schedule a callback for when that happens.
  395. EXPECT_TRUE(eval_ctx_->RunOnValueChangeOrTimeout(
  396. #if BASE_VER < 576279
  397. Bind(&base::DoNothing)
  398. #else
  399. base::DoNothing()
  400. #endif
  401. ));
  402. }
  403. TEST_F(UmEvaluationContextTest,
  404. IsWallclockTimeGreaterThanDoesntRecordPastTimestamps) {
  405. // IsWallclockTimeGreaterThan() should ignore timestamps on the past for
  406. // reevaluation.
  407. EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
  408. fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(20)));
  409. EXPECT_TRUE(eval_ctx_->IsWallclockTimeGreaterThan(
  410. fake_clock_.GetWallclockTime() - TimeDelta::FromSeconds(1)));
  411. // Callback should not be scheduled.
  412. EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(
  413. #if BASE_VER < 576279
  414. Bind(&base::DoNothing)
  415. #else
  416. base::DoNothing()
  417. #endif
  418. ));
  419. }
  420. TEST_F(UmEvaluationContextTest,
  421. IsMonotonicTimeGreaterThanDoesntRecordPastTimestamps) {
  422. // IsMonotonicTimeGreaterThan() should ignore timestamps on the past for
  423. // reevaluation.
  424. EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
  425. fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(20)));
  426. EXPECT_TRUE(eval_ctx_->IsMonotonicTimeGreaterThan(
  427. fake_clock_.GetMonotonicTime() - TimeDelta::FromSeconds(1)));
  428. // Callback should not be scheduled.
  429. EXPECT_FALSE(eval_ctx_->RunOnValueChangeOrTimeout(
  430. #if BASE_VER < 576279
  431. Bind(&base::DoNothing)
  432. #else
  433. base::DoNothing()
  434. #endif
  435. ));
  436. }
  437. TEST_F(UmEvaluationContextTest, DumpContext) {
  438. // |fail_var_| yield "(no value)" since it is unset.
  439. eval_ctx_->GetValue(&fail_var_);
  440. // Check that this is included.
  441. fake_int_var_.reset(new int(42));
  442. eval_ctx_->GetValue(&fake_int_var_);
  443. // Check that double-quotes are escaped properly.
  444. fake_poll_var_.reset(new string("Hello \"world\"!"));
  445. eval_ctx_->GetValue(&fake_poll_var_);
  446. // Note that the variables are printed in alphabetical order. Also
  447. // see UmEvaluationContextText::SetUp() where the values used for
  448. // |evaluation_start_{monotonic,wallclock| are set.
  449. EXPECT_EQ(
  450. "{\n"
  451. " \"evaluation_start_monotonic\": \"4/22/2009 19:25:00 GMT\",\n"
  452. " \"evaluation_start_wallclock\": \"3/2/2006 1:23:45 GMT\",\n"
  453. " \"variables\": {\n"
  454. " \"fail_var\": \"(no value)\",\n"
  455. " \"fake_int\": \"42\",\n"
  456. " \"fake_poll\": \"Hello \\\"world\\\"!\"\n"
  457. " }\n"
  458. "}",
  459. eval_ctx_->DumpContext());
  460. }
  461. } // namespace chromeos_update_manager