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: 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 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 78 TEST_F(BrowserThreadTest, Release) { 79 BrowserThread::ReleaseSoon(BrowserThread::UI, FROM_HERE, this); 80 base::MessageLoop::current()->Run(); 81 } 82 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 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 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 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