1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h"
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/task.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/timer.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::TimeDelta;
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass OneShotTimerTester {
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : did_run_(did_run),
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        delay_ms_(milliseconds) {
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Start() {
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timer_.Start(TimeDelta::FromMilliseconds(delay_ms_), this,
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 &OneShotTimerTester::Run);
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Run() {
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *did_run_ = true;
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop::current()->Quit();
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool* did_run_;
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::OneShotTimer<OneShotTimerTester> timer_;
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const unsigned delay_ms_;
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass OneShotSelfDeletingTimerTester {
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit OneShotSelfDeletingTimerTester(bool* did_run) :
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      did_run_(did_run),
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      timer_(new base::OneShotTimer<OneShotSelfDeletingTimerTester>()) {
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Start() {
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timer_->Start(TimeDelta::FromMilliseconds(10), this,
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                  &OneShotSelfDeletingTimerTester::Run);
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Run() {
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *did_run_ = true;
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timer_.reset();
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MessageLoop::current()->Quit();
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool* did_run_;
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<base::OneShotTimer<OneShotSelfDeletingTimerTester> > timer_;
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RepeatingTimerTester {
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit RepeatingTimerTester(bool* did_run)
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : did_run_(did_run), counter_(10) {
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Start() {
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timer_.Start(TimeDelta::FromMilliseconds(10), this,
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 &RepeatingTimerTester::Run);
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Run() {
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (--counter_ == 0) {
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      *did_run_ = true;
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      MessageLoop::current()->Quit();
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool* did_run_;
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int counter_;
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::RepeatingTimer<RepeatingTimerTester> timer_;
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_OneShotTimer(MessageLoop::Type message_loop_type) {
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester f(&did_run);
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  f.Start();
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(did_run);
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_OneShotTimer_Cancel(MessageLoop::Type message_loop_type) {
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run_a = false;
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This should run before the timer expires.
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->DeleteSoon(FROM_HERE, a);
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now start the timer.
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  a->Start();
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run_b = false;
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester b(&did_run_b);
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  b.Start();
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(did_run_a);
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(did_run_b);
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotSelfDeletingTimerTester f(&did_run);
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  f.Start();
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(did_run);
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_RepeatingTimer(MessageLoop::Type message_loop_type) {
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RepeatingTimerTester f(&did_run);
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  f.Start();
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(did_run);
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type) {
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run_a = false;
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a);
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This should run before the timer expires.
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->DeleteSoon(FROM_HERE, a);
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now start the timer.
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  a->Start();
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run_b = false;
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RepeatingTimerTester b(&did_run_b);
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  b.Start();
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(did_run_a);
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(did_run_b);
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass DelayTimerTarget {
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayTimerTarget()
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : signaled_(false) {
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool signaled() const { return signaled_; }
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Signal() {
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_FALSE(signaled_);
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    signaled_ = true;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool signaled_;
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If Delay is never called, the timer shouldn't go off.
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayTimerTarget target;
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::DelayTimer<DelayTimerTarget> timer(
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester tester(&did_run);
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  tester.Start();
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_FALSE(target.signaled());
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayTimerTarget target;
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::DelayTimer<DelayTimerTarget> timer(
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TimeDelta::FromMilliseconds(1), &target, &DelayTimerTarget::Signal);
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer.Reset();
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester tester(&did_run, 100 /* milliseconds */);
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  tester.Start();
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(target.signaled());
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct ResetHelper {
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ResetHelper(base::DelayTimer<DelayTimerTarget>* timer,
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              DelayTimerTarget* target)
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : timer_(timer),
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        target_(target) {
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Reset() {
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_FALSE(target_->signaled());
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timer_->Reset();
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::DelayTimer<DelayTimerTarget> *const timer_;
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayTimerTarget *const target_;
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If Delay is never called, the timer shouldn't go off.
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayTimerTarget target;
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::DelayTimer<DelayTimerTarget> timer(
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TimeDelta::FromMilliseconds(50), &target, &DelayTimerTarget::Signal);
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer.Reset();
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ResetHelper reset_helper(&timer, &target);
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::OneShotTimer<ResetHelper> timers[20];
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < arraysize(timers); ++i) {
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timers[i].Start(TimeDelta::FromMilliseconds(i * 10), &reset_helper,
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    &ResetHelper::Reset);
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  OneShotTimerTester tester(&did_run, 300);
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  tester.Start();
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->Run();
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(target.signaled());
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass DelayTimerFatalTarget {
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Signal() {
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_TRUE(false);
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop loop(message_loop_type);
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DelayTimerFatalTarget target;
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    base::DelayTimer<DelayTimerFatalTarget> timer(
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        TimeDelta::FromMilliseconds(50), &target,
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        &DelayTimerFatalTarget::Signal);
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timer.Reset();
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // When the timer is deleted, the DelayTimerFatalTarget should never be
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // called.
2703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(100);
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//-----------------------------------------------------------------------------
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Each test is run against each type of MessageLoop.  That way we are sure
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that timers work properly in all configurations.
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, OneShotTimer) {
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotTimer(MessageLoop::TYPE_DEFAULT);
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotTimer(MessageLoop::TYPE_UI);
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotTimer(MessageLoop::TYPE_IO);
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, OneShotTimer_Cancel) {
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_DEFAULT);
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_UI);
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotTimer_Cancel(MessageLoop::TYPE_IO);
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If underline timer does not handle properly, we will crash or fail
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in full page heap or purify environment.
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, OneShotSelfDeletingTimer) {
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_DEFAULT);
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_UI);
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_OneShotSelfDeletingTimer(MessageLoop::TYPE_IO);
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, RepeatingTimer) {
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_RepeatingTimer(MessageLoop::TYPE_DEFAULT);
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_RepeatingTimer(MessageLoop::TYPE_UI);
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_RepeatingTimer(MessageLoop::TYPE_IO);
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, RepeatingTimer_Cancel) {
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_DEFAULT);
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_UI);
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_RepeatingTimer_Cancel(MessageLoop::TYPE_IO);
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, DelayTimer_NoCall) {
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_NoCall(MessageLoop::TYPE_DEFAULT);
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_NoCall(MessageLoop::TYPE_UI);
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_NoCall(MessageLoop::TYPE_IO);
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, DelayTimer_OneCall) {
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_OneCall(MessageLoop::TYPE_DEFAULT);
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_OneCall(MessageLoop::TYPE_UI);
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_OneCall(MessageLoop::TYPE_IO);
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// It's flaky on the buildbot, http://crbug.com/25038.
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, FLAKY_DelayTimer_Reset) {
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_Reset(MessageLoop::TYPE_DEFAULT);
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_Reset(MessageLoop::TYPE_UI);
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_Reset(MessageLoop::TYPE_IO);
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, DelayTimer_Deleted) {
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_Deleted(MessageLoop::TYPE_DEFAULT);
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_Deleted(MessageLoop::TYPE_UI);
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RunTest_DelayTimer_Deleted(MessageLoop::TYPE_IO);
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(TimerTest, MessageLoopShutdown) {
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This test is designed to verify that shutdown of the
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // message loop does not cause crashes if there were pending
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // timers not yet fired.  It may only trigger exceptions
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // if debug heap checking (or purify) is enabled.
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool did_run = false;
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    OneShotTimerTester a(&did_run);
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    OneShotTimerTester b(&did_run);
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    OneShotTimerTester c(&did_run);
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    OneShotTimerTester d(&did_run);
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      MessageLoop loop(MessageLoop::TYPE_DEFAULT);
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      a.Start();
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      b.Start();
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }  // MessageLoop destructs by falling out of scope.
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }  // OneShotTimers destruct.  SHOULD NOT CRASH, of course.
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(did_run);
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
356