15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/browser_thread_model_worker.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::OneShotTimer;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Thread;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncBrowserThreadModelWorkerTest : public testing::Test {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncBrowserThreadModelWorkerTest() :
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_do_work_(false),
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP |
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     content::TestBrowserThreadBundle::REAL_DB_THREAD),
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_do_work() { return did_do_work_; }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThreadModelWorker* worker() { return worker_.get(); }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneShotTimer<SyncBrowserThreadModelWorkerTest>* timer() { return &timer_; }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<SyncBrowserThreadModelWorkerTest>* factory() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &weak_factory_;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedule DoWork to be executed on the DB thread and have the test fail if
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DoWork hasn't executed within action_timeout().
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleWork() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // We wait until the callback is done. So it is safe to use unretained.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syncer::WorkCallback c =
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SyncBrowserThreadModelWorkerTest::DoWork,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timer()->Start(
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestTimeouts::action_timeout(),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &SyncBrowserThreadModelWorkerTest::Timeout);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker()->DoWorkAndWaitUntilDone(c);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the work that will be scheduled to be done on the DB thread.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syncer::SyncerError DoWork() {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timer_.Stop();  // Stop the failure timer so the test succeeds.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        BrowserThread::IO, FROM_HERE, base::MessageLoop::QuitClosure());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    did_do_work_ = true;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return syncer::SYNCER_OK;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will be called by the OneShotTimer and make the test fail unless
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DoWork is called first.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Timeout() {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << "Timed out waiting for work to be done on the DB thread.";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        BrowserThread::IO, FROM_HERE, base::MessageLoop::QuitClosure());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    worker_ = new DatabaseModelWorker(NULL);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Teardown() {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_ = NULL;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_do_work_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserThreadModelWorker> worker_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneShotTimer<SyncBrowserThreadModelWorkerTest> timer_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<SyncBrowserThreadModelWorkerTest> weak_factory_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncBrowserThreadModelWorkerTest, DoesWorkOnDatabaseThread) {
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SyncBrowserThreadModelWorkerTest::ScheduleWork,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 factory()->GetWeakPtr()));
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(did_do_work());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace browser_sync
104