blob: 6ce5bf1201ca50fcb1e5ed044d543bd9ce9619df [file] [log] [blame]
[email protected]d9ddc962010-08-24 04:29:561// Copyright (c) 2010 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/basictypes.h"
6#include "base/logging.h"
[email protected]d9ddc962010-08-24 04:29:567#include "base/scoped_ptr.h"
[email protected]ce072a72010-12-31 20:02:168#include "base/threading/thread_checker.h"
[email protected]ac9ba8fe2010-12-30 18:08:369#include "base/threading/simple_thread.h"
[email protected]d9ddc962010-08-24 04:29:5610#include "testing/gtest/include/gtest/gtest.h"
11
12#ifndef NDEBUG
13
[email protected]ce072a72010-12-31 20:02:1614namespace base {
15
[email protected]d9ddc962010-08-24 04:29:5616// Simple class to exersice the basics of ThreadChecker.
17// Both the destructor and DoStuff should verify that they were
18// called on the same thread as the constructor.
19class ThreadCheckerClass : public ThreadChecker {
20 public:
21 ThreadCheckerClass() {}
22
23 // Verifies that it was called on the same thread as the constructor.
24 void DoStuff() {
25 DCHECK(CalledOnValidThread());
26 }
27
[email protected]8ff672512010-10-07 20:17:3328 void DetachFromThread() {
29 ThreadChecker::DetachFromThread();
30 }
31
[email protected]d9ddc962010-08-24 04:29:5632 private:
33 DISALLOW_COPY_AND_ASSIGN(ThreadCheckerClass);
34};
35
36// Calls ThreadCheckerClass::DoStuff on another thread.
37class CallDoStuffOnThread : public base::SimpleThread {
38 public:
39 CallDoStuffOnThread(ThreadCheckerClass* thread_checker_class)
40 : SimpleThread("call_do_stuff_on_thread"),
41 thread_checker_class_(thread_checker_class) {
42 }
43
44 virtual void Run() {
45 thread_checker_class_->DoStuff();
46 }
47
48 private:
49 ThreadCheckerClass* thread_checker_class_;
50
51 DISALLOW_COPY_AND_ASSIGN(CallDoStuffOnThread);
52};
53
54// Deletes ThreadCheckerClass on a different thread.
55class DeleteThreadCheckerClassOnThread : public base::SimpleThread {
56 public:
57 DeleteThreadCheckerClassOnThread(ThreadCheckerClass* thread_checker_class)
58 : SimpleThread("delete_thread_checker_class_on_thread"),
59 thread_checker_class_(thread_checker_class) {
60 }
61
62 virtual void Run() {
63 thread_checker_class_.reset();
64 }
65
66 private:
67 scoped_ptr<ThreadCheckerClass> thread_checker_class_;
68
69 DISALLOW_COPY_AND_ASSIGN(DeleteThreadCheckerClassOnThread);
70};
71
72TEST(ThreadCheckerTest, CallsAllowedOnSameThread) {
73 scoped_ptr<ThreadCheckerClass> thread_checker_class(
74 new ThreadCheckerClass);
75
76 // Verify that DoStuff doesn't assert.
77 thread_checker_class->DoStuff();
78
79 // Verify that the destructor doesn't assert.
80 thread_checker_class.reset();
81}
82
83TEST(ThreadCheckerTest, DestructorAllowedOnDifferentThread) {
84 scoped_ptr<ThreadCheckerClass> thread_checker_class(
85 new ThreadCheckerClass);
86
87 // Verify that the destructor doesn't assert
88 // when called on a different thread.
89 DeleteThreadCheckerClassOnThread delete_on_thread(
90 thread_checker_class.release());
91
92 delete_on_thread.Start();
93 delete_on_thread.Join();
94}
95
[email protected]8ff672512010-10-07 20:17:3396TEST(ThreadCheckerTest, DetachFromThread) {
97 scoped_ptr<ThreadCheckerClass> thread_checker_class(
98 new ThreadCheckerClass);
99
100 // Verify that DoStuff doesn't assert when called on a different thread after
101 // a call to DetachFromThread.
102 thread_checker_class->DetachFromThread();
103 CallDoStuffOnThread call_on_thread(thread_checker_class.get());
104
105 call_on_thread.Start();
106 call_on_thread.Join();
107}
108
[email protected]d9ddc962010-08-24 04:29:56109#if GTEST_HAS_DEATH_TEST
110
111TEST(ThreadCheckerDeathTest, MethodNotAllowedOnDifferentThread) {
112 ASSERT_DEBUG_DEATH({
113 scoped_ptr<ThreadCheckerClass> thread_checker_class(
114 new ThreadCheckerClass);
115
116 // Verify that DoStuff asserts when called on a different thread.
117 CallDoStuffOnThread call_on_thread(thread_checker_class.get());
118
119 call_on_thread.Start();
120 call_on_thread.Join();
121 }, "");
122}
123
[email protected]8ff672512010-10-07 20:17:33124TEST(ThreadCheckerDeathTest, DetachFromThread) {
125 ASSERT_DEBUG_DEATH({
126 scoped_ptr<ThreadCheckerClass> thread_checker_class(
127 new ThreadCheckerClass);
128
129 // Verify that DoStuff doesn't assert when called on a different thread
130 // after a call to DetachFromThread.
131 thread_checker_class->DetachFromThread();
132 CallDoStuffOnThread call_on_thread(thread_checker_class.get());
133
134 call_on_thread.Start();
135 call_on_thread.Join();
136
137 // Verify that DoStuff asserts after moving to another thread.
138 thread_checker_class->DoStuff();
139 }, "");
140}
141
[email protected]d9ddc962010-08-24 04:29:56142#endif // GTEST_HAS_DEATH_TEST
143
[email protected]ce072a72010-12-31 20:02:16144} // namespace base
145
[email protected]d9ddc962010-08-24 04:29:56146#endif // NDEBUG