1// Copyright 2014 The Chromium 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
5#include "chrome/browser/metrics/variations/variations_request_scheduler_mobile.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "base/prefs/pref_registry_simple.h"
10#include "base/prefs/testing_pref_service.h"
11#include "chrome/common/pref_names.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace chrome_variations {
15
16namespace {
17
18// Simple method used to verify a Callback has been triggered.
19void Increment(int *n) {
20  (*n)++;
21}
22
23}  // namespace
24
25TEST(VariationsRequestSchedulerMobileTest, StartNoRun) {
26  TestingPrefServiceSimple prefs;
27  // Initialize to as if it was just fetched. This means it should not run.
28  prefs.registry()->RegisterInt64Pref(prefs::kVariationsLastFetchTime,
29                                      base::Time::Now().ToInternalValue());
30  int executed = 0;
31  const base::Closure task = base::Bind(&Increment, &executed);
32  VariationsRequestSchedulerMobile scheduler(task, &prefs);
33  scheduler.Start();
34  // We expect it the task to not have triggered.
35  EXPECT_EQ(0, executed);
36}
37
38TEST(VariationsRequestSchedulerMobileTest, StartRun) {
39  TestingPrefServiceSimple prefs;
40  // Verify it doesn't take more than a day.
41  base::Time old = base::Time::Now() - base::TimeDelta::FromHours(24);
42  prefs.registry()->RegisterInt64Pref(prefs::kVariationsLastFetchTime,
43                                      old.ToInternalValue());
44  int executed = 0;
45  const base::Closure task = base::Bind(&Increment, &executed);
46  VariationsRequestSchedulerMobile scheduler(task, &prefs);
47  scheduler.Start();
48  // We expect the task to have triggered.
49  EXPECT_EQ(1, executed);
50}
51
52TEST(VariationsRequestSchedulerMobileTest, OnAppEnterForegroundNoRun) {
53  base::MessageLoopForUI message_loop_;
54
55  TestingPrefServiceSimple prefs;
56
57  // Initialize to as if it was just fetched. This means it should not run.
58  prefs.registry()->RegisterInt64Pref(prefs::kVariationsLastFetchTime,
59                                      base::Time::Now().ToInternalValue());
60  int executed = 0;
61  const base::Closure task = base::Bind(&Increment, &executed);
62  VariationsRequestSchedulerMobile scheduler(task, &prefs);
63
64  // Verify timer not running.
65  EXPECT_FALSE(scheduler.schedule_fetch_timer_.IsRunning());
66  scheduler.OnAppEnterForeground();
67
68  // Timer now running.
69  EXPECT_TRUE(scheduler.schedule_fetch_timer_.IsRunning());
70
71  // Force execution of the task on this timer to verify that the correct task
72  // was added to the timer.
73  scheduler.schedule_fetch_timer_.user_task().Run();
74
75  // The task should not execute because the seed was fetched too recently.
76  EXPECT_EQ(0, executed);
77}
78
79TEST(VariationsRequestSchedulerMobileTest, OnAppEnterForegroundRun) {
80  base::MessageLoopForUI message_loop_;
81
82  TestingPrefServiceSimple prefs;
83
84  base::Time old = base::Time::Now() - base::TimeDelta::FromHours(24);
85  prefs.registry()->RegisterInt64Pref(prefs::kVariationsLastFetchTime,
86                                      old.ToInternalValue());
87  int executed = 0;
88  const base::Closure task = base::Bind(&Increment, &executed);
89  VariationsRequestSchedulerMobile scheduler(task, &prefs);
90
91  // Verify timer not running.
92  EXPECT_FALSE(scheduler.schedule_fetch_timer_.IsRunning());
93  scheduler.OnAppEnterForeground();
94
95  // Timer now running.
96  EXPECT_TRUE(scheduler.schedule_fetch_timer_.IsRunning());
97
98  // Force execution of the task on this timer to verify that the correct task
99  // was added to the timer - this will verify that the right task is running.
100  scheduler.schedule_fetch_timer_.user_task().Run();
101
102  // We expect the input task to have triggered.
103  EXPECT_EQ(1, executed);
104}
105
106TEST(VariationsRequestSchedulerMobileTest, OnAppEnterForegroundOnStartup) {
107  base::MessageLoopForUI message_loop_;
108
109  TestingPrefServiceSimple prefs;
110
111  base::Time old = base::Time::Now() - base::TimeDelta::FromHours(24);
112  prefs.registry()->RegisterInt64Pref(prefs::kVariationsLastFetchTime,
113                                      old.ToInternalValue());
114  int executed = 0;
115  const base::Closure task = base::Bind(&Increment, &executed);
116  VariationsRequestSchedulerMobile scheduler(task, &prefs);
117
118  scheduler.Start();
119
120  // We expect the task to have triggered.
121  EXPECT_EQ(1, executed);
122
123  scheduler.OnAppEnterForeground();
124
125  EXPECT_FALSE(scheduler.schedule_fetch_timer_.IsRunning());
126  // We expect the input task to not have triggered again, so executed stays
127  // at 1.
128  EXPECT_EQ(1, executed);
129
130  // Simulate letting time pass.
131  const base::Time last_fetch_time = base::Time::FromInternalValue(
132      prefs.GetInt64(prefs::kVariationsLastFetchTime));
133  prefs.SetInt64(
134      prefs::kVariationsLastFetchTime,
135      (last_fetch_time - base::TimeDelta::FromHours(24)).ToInternalValue());
136  scheduler.last_request_time_ -= base::TimeDelta::FromHours(24);
137
138  scheduler.OnAppEnterForeground();
139  EXPECT_TRUE(scheduler.schedule_fetch_timer_.IsRunning());
140  scheduler.schedule_fetch_timer_.user_task().Run();
141  // This time it should execute the task.
142  EXPECT_EQ(2, executed);
143}
144
145}  // namespace chrome_variations
146