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/bind_helpers.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/browser_thread_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserThreadTest : public testing::Test {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Release() const {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI));
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_.reset(new BrowserThreadImpl(BrowserThread::FILE));
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_thread_->Start();
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_->Start();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_thread_->Stop();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_->Stop();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static void BasicFunction(base::MessageLoop* message_loop) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DeletedOnFile
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : public base::RefCountedThreadSafe<
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DeletedOnFile, BrowserThread::DeleteOnFileThread> {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DeletedOnFile(base::MessageLoop* message_loop)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : message_loop_(message_loop) {}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend class base::DeleteHelper<DeletedOnFile>;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~DeletedOnFile() {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop* message_loop_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BrowserThreadImpl> ui_thread_;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BrowserThreadImpl> file_thread_;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's kind of ugly to make this mutable - solely so we can post the Quit
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Task from Release(). This should be fixed.
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mutable base::MessageLoop loop_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BrowserThreadTest, PostTask) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      BrowserThread::FILE,
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&BasicFunction, base::MessageLoop::current()));
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BrowserThreadTest, Release) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::ReleaseSoon(BrowserThread::UI, FROM_HERE, this);
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<DeletedOnFile> test(
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new DeletedOnFile(base::MessageLoop::current()));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BrowserThreadTest, PostTaskViaMessageLoopProxy) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_proxy->PostTask(
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE, base::Bind(&BasicFunction, base::MessageLoop::current()));
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BrowserThreadTest, ReleaseViaMessageLoopProxy) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_proxy->ReleaseSoon(FROM_HERE, this);
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BrowserThreadTest, PostTaskAndReply) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most of the heavy testing for PostTaskAndReply() is done inside the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoopProxy test.  This just makes sure we get piped through at all.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::PostTaskAndReply(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&base::DoNothing),
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&base::MessageLoop::Quit,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(base::MessageLoop::current()->current()))));
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace content
119