15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/basictypes.h"
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/bind.h"
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/location.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/run_loop.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/timed_task_helper.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::TimedTaskHelper;
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace content {
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class Embedder {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Embedder()
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : timer_(base::MessageLoopProxy::current().get()), timer_fired_(false) {}
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void OnTimerFired() {
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    timer_fired_ = true;
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimedTaskHelper* timer() { return &timer_; }
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool timer_fired() const { return timer_fired_; }
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TimedTaskHelper timer_;
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool timer_fired_;
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST(TimedTaskHelper, FireTimerWhenAlive) {
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::MessageLoop message_loop;
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Embedder embedder;
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_FALSE(embedder.timer_fired());
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_FALSE(embedder.timer()->IsRunning());
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  embedder.timer()->Start(
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FROM_HERE,
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::TimeDelta::FromSeconds(0),
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&Embedder::OnTimerFired, base::Unretained(&embedder)));
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_TRUE(embedder.timer()->IsRunning());
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  embedder.timer()->Reset();
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_TRUE(embedder.timer()->IsRunning());
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_TRUE(embedder.timer_fired());
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST(TimedTaskHelper, FireTimerWhenAlreadyDeleted) {
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::MessageLoop message_loop;
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Run message loop after embedder is already deleted to make sure callback
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // doesn't cause a crash for use after free.
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  {
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Embedder embedder;
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_FALSE(embedder.timer_fired());
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_FALSE(embedder.timer()->IsRunning());
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    embedder.timer()->Start(
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        FROM_HERE,
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::TimeDelta::FromSeconds(0),
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&Embedder::OnTimerFired, base::Unretained(&embedder)));
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(embedder.timer()->IsRunning());
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // At this point the callback is still in the message queue but
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // embedder is gone.
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace content
86