1// Copyright (c) 2011 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 "base/callback.h" 6#include "base/memory/scoped_ptr.h" 7#include "base/message_loop.h" 8#include "base/threading/thread.h" 9#include "base/timer.h" 10#include "chrome/browser/sync/glue/database_model_worker.h" 11#include "content/browser/browser_thread.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14using base::OneShotTimer; 15using base::Thread; 16using base::TimeDelta; 17using browser_sync::DatabaseModelWorker; 18 19namespace { 20 21class DatabaseModelWorkerTest : public testing::Test { 22 public: 23 DatabaseModelWorkerTest() : 24 did_do_work_(false), 25 db_thread_(BrowserThread::DB), 26 io_thread_(BrowserThread::IO, &io_loop_), 27 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} 28 29 bool did_do_work() { return did_do_work_; } 30 DatabaseModelWorker* worker() { return worker_.get(); } 31 OneShotTimer<DatabaseModelWorkerTest>* timer() { return &timer_; } 32 ScopedRunnableMethodFactory<DatabaseModelWorkerTest>* factory() { 33 return &method_factory_; 34 } 35 36 // Schedule DoWork to be executed on the DB thread and have the test fail if 37 // DoWork hasn't executed within 10 seconds. 38 void ScheduleWork() { 39 scoped_ptr<Callback0::Type> c(NewCallback(this, 40 &DatabaseModelWorkerTest::DoWork)); 41 timer()->Start(TimeDelta::FromSeconds(10), 42 this, &DatabaseModelWorkerTest::Timeout); 43 worker()->DoWorkAndWaitUntilDone(c.get()); 44 } 45 46 // This is the work that will be scheduled to be done on the DB thread. 47 void DoWork() { 48 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB)); 49 timer_.Stop(); // Stop the failure timer so the test succeeds. 50 BrowserThread::PostTask( 51 BrowserThread::IO, FROM_HERE, new MessageLoop::QuitTask()); 52 did_do_work_ = true; 53 } 54 55 // This will be called by the OneShotTimer and make the test fail unless 56 // DoWork is called first. 57 void Timeout() { 58 ADD_FAILURE() << "Timed out waiting for work to be done on the DB thread."; 59 BrowserThread::PostTask( 60 BrowserThread::IO, FROM_HERE, new MessageLoop::QuitTask()); 61 } 62 63 protected: 64 virtual void SetUp() { 65 db_thread_.Start(); 66 worker_ = new DatabaseModelWorker(); 67 } 68 69 virtual void Teardown() { 70 worker_.release(); 71 db_thread_.Stop(); 72 } 73 74 private: 75 bool did_do_work_; 76 scoped_refptr<DatabaseModelWorker> worker_; 77 OneShotTimer<DatabaseModelWorkerTest> timer_; 78 79 BrowserThread db_thread_; 80 MessageLoopForIO io_loop_; 81 BrowserThread io_thread_; 82 83 ScopedRunnableMethodFactory<DatabaseModelWorkerTest> method_factory_; 84}; 85 86TEST_F(DatabaseModelWorkerTest, DoesWorkOnDatabaseThread) { 87 MessageLoop::current()->PostTask(FROM_HERE, factory()->NewRunnableMethod( 88 &DatabaseModelWorkerTest::ScheduleWork)); 89 MessageLoop::current()->Run(); 90 EXPECT_TRUE(did_do_work()); 91} 92 93} // namespace 94