1fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/basictypes.h"
6fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/bind.h"
7fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/bind_helpers.h"
8fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/location.h"
9fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/logging.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/memory/ref_counted.h"
11fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/memory/scoped_ptr.h"
12fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/message_loop/message_loop.h"
13fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/sequence_checker.h"
14fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/test/sequenced_worker_pool_owner.h"
15fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/threading/thread.h"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
18fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// Duplicated from base/sequence_checker.h so that we can be good citizens
19fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// there and undef the macro.
20fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
21fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#define ENABLE_SEQUENCE_CHECKER 1
22fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#else
23fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#define ENABLE_SEQUENCE_CHECKER 0
24fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif
25fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochconst size_t kNumWorkerThreads = 3;
31fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
32fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// Simple class to exercise the basics of SequenceChecker.
33fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// DoStuff should verify that it's called on a valid sequenced thread.
34fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// SequenceCheckedObject can be destroyed on any thread (like WeakPtr).
35fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochclass SequenceCheckedObject {
36fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch public:
37fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  SequenceCheckedObject() {}
38fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ~SequenceCheckedObject() {}
39fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
40fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Verifies that it was called on the same thread as the constructor.
41fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void DoStuff() {
42fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    DCHECK(sequence_checker_.CalledOnValidSequencedThread());
43fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
44fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
45fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void DetachFromSequence() {
46fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    sequence_checker_.DetachFromSequence();
47fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
48fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
49fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch private:
50fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  SequenceChecker sequence_checker_;
51fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
52fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(SequenceCheckedObject);
53fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch};
54fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
55fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochclass SequenceCheckerTest : public testing::Test {
56fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch public:
57fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  SequenceCheckerTest() : other_thread_("sequence_checker_test_other_thread") {}
58fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
59fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  virtual ~SequenceCheckerTest() {}
60fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
61fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  virtual void SetUp() OVERRIDE {
62fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    other_thread_.Start();
63fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    ResetPool();
64fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
65fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
66fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  virtual void TearDown() OVERRIDE {
67fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    other_thread_.Stop();
68fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    pool()->Shutdown();
69fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
70fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
71fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch protected:
72fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  base::Thread* other_thread() { return &other_thread_; }
73fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
74fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  const scoped_refptr<SequencedWorkerPool>& pool() {
75fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    return pool_owner_->pool();
76fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
77fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
78fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void PostDoStuffToWorkerPool(SequenceCheckedObject* sequence_checked_object,
79fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch                               const std::string& token_name) {
80fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    pool()->PostNamedSequencedWorkerTask(
81fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        token_name,
82fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        FROM_HERE,
83fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        base::Bind(&SequenceCheckedObject::DoStuff,
84fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch                   base::Unretained(sequence_checked_object)));
85fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
86fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
87fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void PostDoStuffToOtherThread(
88fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      SequenceCheckedObject* sequence_checked_object) {
89fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    other_thread()->message_loop()->PostTask(
90fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        FROM_HERE,
91fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        base::Bind(&SequenceCheckedObject::DoStuff,
92fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch                   base::Unretained(sequence_checked_object)));
93fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
94fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
95fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void PostDeleteToOtherThread(
96fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      scoped_ptr<SequenceCheckedObject> sequence_checked_object) {
97fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    other_thread()->message_loop()->DeleteSoon(
98fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        FROM_HERE,
99fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch        sequence_checked_object.release());
100fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
101fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
102fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Destroys the SequencedWorkerPool instance, blocking until it is fully shut
103fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // down, and creates a new instance.
104fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void ResetPool() {
105fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test"));
106fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }
107fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
108fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void MethodOnDifferentThreadDeathTest();
109fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void DetachThenCallFromDifferentThreadDeathTest();
110fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void DifferentSequenceTokensDeathTest();
111fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void WorkerPoolAndSimpleThreadDeathTest();
112fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  void TwoDifferentWorkerPoolsDeathTest();
113fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
114fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch private:
115fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  MessageLoop message_loop_;  // Needed by SequencedWorkerPool to function.
116fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  base::Thread other_thread_;
117fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequencedWorkerPoolOwner> pool_owner_;
118fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch};
119fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
120fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, CallsAllowedOnSameThread) {
121fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
122fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
123fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
124fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Verify that DoStuff doesn't assert.
125fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DoStuff();
126fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
127fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Verify that the destructor doesn't assert.
128fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object.reset();
129fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
130fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
131fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, DestructorAllowedOnDifferentThread) {
132fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
133fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
134fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
135fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Verify the destructor doesn't assert when called on a different thread.
136fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDeleteToOtherThread(sequence_checked_object.Pass());
137fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
138fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
139fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
140fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, DetachFromSequence) {
141fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
142fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
143fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
144fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Verify that DoStuff doesn't assert when called on a different thread after
145fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // a call to DetachFromSequence.
146fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
147fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
148fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToOtherThread(sequence_checked_object.get());
149fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
150fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
151fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
152fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, SameSequenceTokenValid) {
153fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
154fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
155fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
156fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
157fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
158fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
159fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
160fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
161fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  pool()->FlushForTesting();
162fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
163fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDeleteToOtherThread(sequence_checked_object.Pass());
164fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
165fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
166fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
167fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, DetachSequenceTokenValid) {
168fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
169fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
170fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
171fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
172fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
173fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
174fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  pool()->FlushForTesting();
175fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
176fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
177fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
178fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
179fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  pool()->FlushForTesting();
180fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
181fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDeleteToOtherThread(sequence_checked_object.Pass());
182fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
183fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
184fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
185fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER
186fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
187fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid SequenceCheckerTest::MethodOnDifferentThreadDeathTest() {
188fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
189fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
190fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
191fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // DoStuff should assert in debug builds only when called on a
192fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // different thread.
193fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToOtherThread(sequence_checked_object.get());
194fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
195fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
196fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
197fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if ENABLE_SEQUENCE_CHECKER
198fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) {
199fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // The default style "fast" does not support multi-threaded tests.
200fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
201fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ASSERT_DEATH({
202fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    MethodOnDifferentThreadDeathTest();
203fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }, "");
204fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
205fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#else
206fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) {
207fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  MethodOnDifferentThreadDeathTest();
208fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
209fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif  // ENABLE_SEQUENCE_CHECKER
210fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
211fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() {
212fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
213fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
214fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
215fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // DoStuff doesn't assert when called on a different thread
216fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // after a call to DetachFromSequence.
217fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
218fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToOtherThread(sequence_checked_object.get());
219fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
220fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
221fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // DoStuff should assert in debug builds only after moving to
222fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // another thread.
223fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DoStuff();
224fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
225fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
226fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if ENABLE_SEQUENCE_CHECKER
227fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) {
228fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // The default style "fast" does not support multi-threaded tests.
229fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
230fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ASSERT_DEATH({
231fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    DetachThenCallFromDifferentThreadDeathTest();
232fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }, "");
233fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
234fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#else
235fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) {
236fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  DetachThenCallFromDifferentThreadDeathTest();
237fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
238fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif  // ENABLE_SEQUENCE_CHECKER
239fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
240fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid SequenceCheckerTest::DifferentSequenceTokensDeathTest() {
241fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
242fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
243fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
244fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
245fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
246fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
247fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
248fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
249fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  pool()->FlushForTesting();
250fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
251fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDeleteToOtherThread(sequence_checked_object.Pass());
252fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if ENABLE_SEQUENCE_CHECKER
256fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) {
257fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // The default style "fast" does not support multi-threaded tests.
258fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
259fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ASSERT_DEATH({
260fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    DifferentSequenceTokensDeathTest();
261fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }, "");
262fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
263fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#else
2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInRelease) {
265fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  DifferentSequenceTokensDeathTest();
266fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
267fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif  // ENABLE_SEQUENCE_CHECKER
268fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
269fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() {
270fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
271fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
272fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
273fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
274fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
275fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
276fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  pool()->FlushForTesting();
277fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
278fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToOtherThread(sequence_checked_object.get());
279fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  other_thread()->Stop();
280fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
281fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
282fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if ENABLE_SEQUENCE_CHECKER
283fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) {
284fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // The default style "fast" does not support multi-threaded tests.
285fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
286fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ASSERT_DEATH({
287fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    WorkerPoolAndSimpleThreadDeathTest();
288fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }, "");
289fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
290fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#else
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInRelease) {
292fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  WorkerPoolAndSimpleThreadDeathTest();
293fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
294fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif  // ENABLE_SEQUENCE_CHECKER
295fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
296fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() {
297fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
298fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      new SequenceCheckedObject);
299fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
300fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  sequence_checked_object->DetachFromSequence();
301fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
302fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
303fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  pool()->FlushForTesting();
304fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
305fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2");
306fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  second_pool_owner.pool()->PostNamedSequencedWorkerTask(
307fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      "A",
308fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      FROM_HERE,
309fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch      base::Bind(&SequenceCheckedObject::DoStuff,
310fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch                 base::Unretained(sequence_checked_object.get())));
311fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  second_pool_owner.pool()->FlushForTesting();
312fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  second_pool_owner.pool()->Shutdown();
313fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
314fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
315fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#if ENABLE_SEQUENCE_CHECKER
316fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochTEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) {
317fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // The default style "fast" does not support multi-threaded tests.
318fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
319fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  ASSERT_DEATH({
320fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch    TwoDifferentWorkerPoolsDeathTest();
321fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  }, "");
322fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
323fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#else
3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInRelease) {
325fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  TwoDifferentWorkerPoolsDeathTest();
326fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch}
327fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif  // ENABLE_SEQUENCE_CHECKER
328fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
329fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#endif  // GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER
330fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace base
334fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
335fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch// Just in case we ever get lumped together with other compilation units.
336fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#undef ENABLE_SEQUENCE_CHECKER
337