1// Copyright (c) 2012 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/bind.h"
6#include "base/bind_helpers.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/message_loop/message_loop.h"
9#include "base/message_loop/message_loop_proxy.h"
10#include "base/sequenced_task_runner_helpers.h"
11#include "content/browser/browser_thread_impl.h"
12#include "content/public/test/test_browser_thread.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "testing/platform_test.h"
15
16namespace content {
17
18class BrowserThreadTest : public testing::Test {
19 public:
20  void Release() const {
21    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
22    loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
23  }
24
25 protected:
26  virtual void SetUp() {
27    ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI));
28    file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
29    ui_thread_->Start();
30    file_thread_->Start();
31  }
32
33  virtual void TearDown() {
34    ui_thread_->Stop();
35    file_thread_->Stop();
36  }
37
38  static void BasicFunction(base::MessageLoop* message_loop) {
39    CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
40    message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
41  }
42
43  class DeletedOnFile
44      : public base::RefCountedThreadSafe<
45            DeletedOnFile, BrowserThread::DeleteOnFileThread> {
46   public:
47    explicit DeletedOnFile(base::MessageLoop* message_loop)
48        : message_loop_(message_loop) {}
49
50   private:
51    friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
52    friend class base::DeleteHelper<DeletedOnFile>;
53
54    ~DeletedOnFile() {
55      CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
56      message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
57    }
58
59    base::MessageLoop* message_loop_;
60  };
61
62 private:
63  scoped_ptr<BrowserThreadImpl> ui_thread_;
64  scoped_ptr<BrowserThreadImpl> file_thread_;
65  // It's kind of ugly to make this mutable - solely so we can post the Quit
66  // Task from Release(). This should be fixed.
67  mutable base::MessageLoop loop_;
68};
69
70TEST_F(BrowserThreadTest, PostTask) {
71  BrowserThread::PostTask(
72      BrowserThread::FILE,
73      FROM_HERE,
74      base::Bind(&BasicFunction, base::MessageLoop::current()));
75  base::MessageLoop::current()->Run();
76}
77
78TEST_F(BrowserThreadTest, Release) {
79  BrowserThread::ReleaseSoon(BrowserThread::UI, FROM_HERE, this);
80  base::MessageLoop::current()->Run();
81}
82
83TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) {
84  {
85    scoped_refptr<DeletedOnFile> test(
86        new DeletedOnFile(base::MessageLoop::current()));
87  }
88  base::MessageLoop::current()->Run();
89}
90
91TEST_F(BrowserThreadTest, PostTaskViaMessageLoopProxy) {
92  scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
93      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
94  message_loop_proxy->PostTask(
95      FROM_HERE, base::Bind(&BasicFunction, base::MessageLoop::current()));
96  base::MessageLoop::current()->Run();
97}
98
99TEST_F(BrowserThreadTest, ReleaseViaMessageLoopProxy) {
100  scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
101      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
102  message_loop_proxy->ReleaseSoon(FROM_HERE, this);
103  base::MessageLoop::current()->Run();
104}
105
106TEST_F(BrowserThreadTest, PostTaskAndReply) {
107  // Most of the heavy testing for PostTaskAndReply() is done inside the
108  // MessageLoopProxy test.  This just makes sure we get piped through at all.
109  ASSERT_TRUE(BrowserThread::PostTaskAndReply(
110      BrowserThread::FILE,
111      FROM_HERE,
112      base::Bind(&base::DoNothing),
113      base::Bind(&base::MessageLoop::Quit,
114                 base::Unretained(base::MessageLoop::current()->current()))));
115  base::MessageLoop::current()->Run();
116}
117
118}  // namespace content
119