1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
83f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/database_model_worker.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::OneShotTimer;
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Thread;
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::DatabaseModelWorker;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DatabaseModelWorkerTest : public testing::Test {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DatabaseModelWorkerTest() :
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      did_do_work_(false),
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      db_thread_(BrowserThread::DB),
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      io_thread_(BrowserThread::IO, &io_loop_),
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {}
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool did_do_work() { return did_do_work_; }
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DatabaseModelWorker* worker() { return worker_.get(); }
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OneShotTimer<DatabaseModelWorkerTest>* timer() { return &timer_; }
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedRunnableMethodFactory<DatabaseModelWorkerTest>* factory() {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &method_factory_;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Schedule DoWork to be executed on the DB thread and have the test fail if
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DoWork hasn't executed within 10 seconds.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ScheduleWork() {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<Callback0::Type> c(NewCallback(this,
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &DatabaseModelWorkerTest::DoWork));
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timer()->Start(TimeDelta::FromSeconds(10),
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   this, &DatabaseModelWorkerTest::Timeout);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    worker()->DoWorkAndWaitUntilDone(c.get());
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is the work that will be scheduled to be done on the DB thread.
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void DoWork() {
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timer_.Stop();  // Stop the failure timer so the test succeeds.
50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::IO, FROM_HERE, new MessageLoop::QuitTask());
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    did_do_work_ = true;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This will be called by the OneShotTimer and make the test fail unless
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DoWork is called first.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Timeout() {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ADD_FAILURE() << "Timed out waiting for work to be done on the DB thread.";
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::IO, FROM_HERE, new MessageLoop::QuitTask());
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    db_thread_.Start();
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    worker_ = new DatabaseModelWorker();
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Teardown() {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    worker_.release();
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    db_thread_.Stop();
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool did_do_work_;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<DatabaseModelWorker> worker_;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OneShotTimer<DatabaseModelWorkerTest> timer_;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread db_thread_;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoopForIO io_loop_;
81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread io_thread_;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedRunnableMethodFactory<DatabaseModelWorkerTest> method_factory_;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(DatabaseModelWorkerTest, DoesWorkOnDatabaseThread) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostTask(FROM_HERE, factory()->NewRunnableMethod(
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &DatabaseModelWorkerTest::ScheduleWork));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(did_do_work());
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
94