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
16 namespace content {
17
18 class BrowserThreadTest : public testing::Test {
19 public:
Release() const20 void Release() const {
21 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
22 loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
23 }
24
25 protected:
SetUp()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
TearDown()33 virtual void TearDown() {
34 ui_thread_->Stop();
35 file_thread_->Stop();
36 }
37
BasicFunction(base::MessageLoop * message_loop)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:
DeletedOnFile(base::MessageLoop * message_loop)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
~DeletedOnFile()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
TEST_F(BrowserThreadTest,PostTask)70 TEST_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
TEST_F(BrowserThreadTest,Release)78 TEST_F(BrowserThreadTest, Release) {
79 BrowserThread::ReleaseSoon(BrowserThread::UI, FROM_HERE, this);
80 base::MessageLoop::current()->Run();
81 }
82
TEST_F(BrowserThreadTest,ReleasedOnCorrectThread)83 TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) {
84 {
85 scoped_refptr<DeletedOnFile> test(
86 new DeletedOnFile(base::MessageLoop::current()));
87 }
88 base::MessageLoop::current()->Run();
89 }
90
TEST_F(BrowserThreadTest,PostTaskViaMessageLoopProxy)91 TEST_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
TEST_F(BrowserThreadTest,ReleaseViaMessageLoopProxy)99 TEST_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
TEST_F(BrowserThreadTest,PostTaskAndReply)106 TEST_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