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