Chromium Code Reviews| Index: base/sequence_checker_impl_unittest.cc |
| diff --git a/base/sequence_checker_impl_unittest.cc b/base/sequence_checker_impl_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..15155f3441acdffd32cf11a8b47c0216afed587d |
| --- /dev/null |
| +++ b/base/sequence_checker_impl_unittest.cc |
| @@ -0,0 +1,209 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/sequence_checker_impl.h" |
| + |
| +#include <cstddef> |
| + |
| +#include "base/bind.h" |
| +#include "base/compiler_specific.h" |
| +#include "base/location.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/message_loop.h" |
| +#include "base/sequenced_task_runner.h" |
| +#include "base/threading/thread.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace base { |
| + |
| +namespace { |
| + |
| +// Implementation of SequencedTaskRunner that lets us control what |
| +// RunsTasksOnCurrentThread() returns. |
| +class FakeTaskRunner : public SequencedTaskRunner { |
| + public: |
| + FakeTaskRunner() : runs_tasks_on_current_thread_(false) {} |
| + |
| + void SetRunsTasksOnCurrentThread(bool runs_tasks_on_current_thread) { |
| + runs_tasks_on_current_thread_ = runs_tasks_on_current_thread; |
| + } |
| + |
| + // SequencedTaskRunner implementation. |
| + virtual bool PostDelayedTask(const tracked_objects::Location& from_here, |
| + const Closure& task, |
| + TimeDelta delay) OVERRIDE { |
| + ADD_FAILURE(); |
| + return false; |
| + } |
| + |
| + virtual bool PostNonNestableDelayedTask( |
| + const tracked_objects::Location& from_here, |
| + const Closure& task, |
| + TimeDelta delay) OVERRIDE { |
| + ADD_FAILURE(); |
| + return false; |
| + } |
| + |
| + virtual bool RunsTasksOnCurrentThread() const OVERRIDE { |
| + return runs_tasks_on_current_thread_; |
| + } |
| + |
| + protected: |
| + virtual ~FakeTaskRunner() {} |
| + |
| + private: |
| + bool runs_tasks_on_current_thread_; |
| +}; |
| + |
| +class SequenceCheckerImplTest : public ::testing::Test { |
| +}; |
| + |
| +// Create a SequenceCheckerImpl with a SequencedTaskRunner and make |
| +// sure that CalledOnValidSequence() returns what that SequencedTaskRunner |
| +// returns for RunsTasksOnCurrentThread(). |
| +TEST_F(SequenceCheckerImplTest, CalledOnValidSequenceNonNull) { |
| + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner( |
| + new FakeTaskRunner()); |
| + |
| + const SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner); |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(true); |
| + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(false); |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| +} |
| + |
| +void ExpectCalledOnValidSequence( |
| + const tracked_objects::Location& location, |
| + const SequenceCheckerImpl* sequence_checker_impl, |
| + bool expected_value) { |
| + EXPECT_EQ(expected_value, sequence_checker_impl->CalledOnValidSequence()) |
| + << location.ToString(); |
| +} |
| + |
| +// Create a SequenceCheckerImpl with no SequencedTaskRunner and make |
| +// sure that CalledOnValidSequence() behaves like |
| +// ThreadChecker::CalledOnValidThread(). |
| +TEST_F(SequenceCheckerImplTest, CalledOnValidSequenceNull) { |
| + const SequenceCheckerImpl sequence_checker_impl(NULL); |
| + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + { |
| + Thread thread("thread 1"); |
| + ASSERT_TRUE(thread.Start()); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&ExpectCalledOnValidSequence, |
| + FROM_HERE, |
| + Unretained(&sequence_checker_impl), |
| + false)); |
| + } |
|
Ryan Sleevi
2012/12/21 20:26:47
I would add one more check here, before exiting, t
akalin
2012/12/21 20:41:40
Done.
|
| +} |
| + |
| +// Create a SequenceCheckerImpl with a SequencedTaskRunner and switch |
| +// it to another one. CalledOnValidSequence() should return what its |
|
Ryan Sleevi
2012/12/21 20:26:47
comment nit: In what will probably prove to be my
akalin
2012/12/21 20:41:40
Done. Not judged.
|
| +// underlying SequencedTaskRunner returns for |
| +// RunsTasksOnCurrentThread(). |
| +TEST_F(SequenceCheckerImplTest, ChangeSequenceNonNull) { |
| + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner1( |
| + new FakeTaskRunner()); |
| + |
| + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner2( |
| + new FakeTaskRunner()); |
| + |
| + SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner1); |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + fake_sequenced_task_runner2->SetRunsTasksOnCurrentThread(true); |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + sequence_checker_impl.ChangeSequence(fake_sequenced_task_runner2); |
| + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); |
|
Ryan Sleevi
2012/12/21 20:26:47
For complete-ness sake in terms of testing, I woul
akalin
2012/12/21 20:41:40
Done.
|
| +} |
| + |
| +// Create a SequenceCheckerImpl with a SequencedTaskRunner and switch |
| +// it to a NULL one. CalledOnValidSequence() should then behave like |
| +// ThreadChecker::CalledOnValidThread(). |
| +TEST_F(SequenceCheckerImplTest, ChangeSequenceNull) { |
| + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner( |
| + new FakeTaskRunner()); |
| + |
| + SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner); |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + sequence_checker_impl.ChangeSequence(NULL); |
| + // Binds to current thread. |
| + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); |
| + { |
| + Thread thread("thread 1"); |
| + ASSERT_TRUE(thread.Start()); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&ExpectCalledOnValidSequence, |
| + FROM_HERE, |
| + Unretained(&sequence_checker_impl), |
| + false)); |
| + } |
| + |
|
Ryan Sleevi
2012/12/21 20:26:47
I'd add an EXPECT_TRUE() here (for the same reason
akalin
2012/12/21 20:41:40
Done.
|
| + sequence_checker_impl.ChangeSequence(NULL); |
| + // Binds to worker thread. |
| + { |
| + Thread thread("thread 2"); |
| + ASSERT_TRUE(thread.Start()); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&ExpectCalledOnValidSequence, |
| + FROM_HERE, |
| + Unretained(&sequence_checker_impl), |
| + true)); |
| + } |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| +} |
| + |
| +// Create a SequenceCheckerImpl with the current thread's task runner |
| +// and switch it to other ones. CalledOnValidSequence() should return true |
|
Ryan Sleevi
2012/12/21 20:26:47
comment nit: "ones" here is a bit weird. You mean
akalin
2012/12/21 20:41:40
Done.
|
| +// only when it's on the correct thread. |
| +TEST_F(SequenceCheckerImplTest, MultipleThreads) { |
| + MessageLoop loop; |
| + |
| + SequenceCheckerImpl sequence_checker_impl(loop.message_loop_proxy()); |
| + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + { |
| + Thread thread("thread 1"); |
| + ASSERT_TRUE(thread.Start()); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&ExpectCalledOnValidSequence, |
| + FROM_HERE, |
| + Unretained(&sequence_checker_impl), |
| + false)); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&SequenceCheckerImpl::ChangeSequence, |
| + Unretained(&sequence_checker_impl), |
| + thread.message_loop_proxy())); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&ExpectCalledOnValidSequence, |
| + FROM_HERE, |
| + Unretained(&sequence_checker_impl), |
| + true)); |
| + } |
| + |
| + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + sequence_checker_impl.ChangeSequence(loop.message_loop_proxy()); |
| + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); |
| + |
| + { |
| + Thread thread("thread 2"); |
| + ASSERT_TRUE(thread.Start()); |
| + thread.message_loop()->PostTask( |
| + FROM_HERE, Bind(&ExpectCalledOnValidSequence, |
| + FROM_HERE, |
| + Unretained(&sequence_checker_impl), |
| + false)); |
| + } |
| +} |
|
Ryan Sleevi
2012/12/21 20:26:47
nit: Add an EXPECT_TRUE here as well (same as line
akalin
2012/12/21 20:41:40
Done.
|
| + |
| +} // namespace |
| + |
| +} // namespace base |