1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/threading/sequence_bound.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <functional>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <string_view>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
22*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
23*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
24*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker namespace base {
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker namespace {
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker class EventLogger {
31*6777b538SAndroid Build Coastguard Worker public:
32*6777b538SAndroid Build Coastguard Worker EventLogger() = default;
33*6777b538SAndroid Build Coastguard Worker
AddEvent(std::string_view event)34*6777b538SAndroid Build Coastguard Worker void AddEvent(std::string_view event) {
35*6777b538SAndroid Build Coastguard Worker AutoLock guard(lock_);
36*6777b538SAndroid Build Coastguard Worker events_.push_back(std::string(event));
37*6777b538SAndroid Build Coastguard Worker }
TakeEvents()38*6777b538SAndroid Build Coastguard Worker std::vector<std::string> TakeEvents() {
39*6777b538SAndroid Build Coastguard Worker AutoLock guard(lock_);
40*6777b538SAndroid Build Coastguard Worker return std::exchange(events_, {});
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker private:
44*6777b538SAndroid Build Coastguard Worker Lock lock_;
45*6777b538SAndroid Build Coastguard Worker std::vector<std::string> events_ GUARDED_BY(lock_);
46*6777b538SAndroid Build Coastguard Worker };
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker // Helpers for writing type tests against both `SequenceBound<T>` and
49*6777b538SAndroid Build Coastguard Worker // `SequenceBound<std::unique_ptr<T>`. The tricky part here is that the
50*6777b538SAndroid Build Coastguard Worker // constructor and emplace both need to accept variadic args; however,
51*6777b538SAndroid Build Coastguard Worker // construction of the actual `T` depends on the storage strategy. The
52*6777b538SAndroid Build Coastguard Worker // `Wrapper` template provides this layer of indirection to construct the
53*6777b538SAndroid Build Coastguard Worker // managed `T` while still passing through all the other remaining
54*6777b538SAndroid Build Coastguard Worker // `SequenceBound` APIs.
55*6777b538SAndroid Build Coastguard Worker struct DirectVariation {
56*6777b538SAndroid Build Coastguard Worker static constexpr bool kManagingTaskRunnerConstructsT = true;
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker template <typename T>
59*6777b538SAndroid Build Coastguard Worker class Wrapper : public SequenceBound<T> {
60*6777b538SAndroid Build Coastguard Worker public:
61*6777b538SAndroid Build Coastguard Worker template <typename... Args>
Wrapper(scoped_refptr<SequencedTaskRunner> task_runner,Args &&...args)62*6777b538SAndroid Build Coastguard Worker explicit Wrapper(scoped_refptr<SequencedTaskRunner> task_runner,
63*6777b538SAndroid Build Coastguard Worker Args&&... args)
64*6777b538SAndroid Build Coastguard Worker : SequenceBound<T>(std::move(task_runner),
65*6777b538SAndroid Build Coastguard Worker std::forward<Args>(args)...) {}
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker template <typename... Args>
WrappedEmplace(scoped_refptr<SequencedTaskRunner> task_runner,Args &&...args)68*6777b538SAndroid Build Coastguard Worker void WrappedEmplace(scoped_refptr<SequencedTaskRunner> task_runner,
69*6777b538SAndroid Build Coastguard Worker Args&&... args) {
70*6777b538SAndroid Build Coastguard Worker this->emplace(std::move(task_runner), std::forward<Args>(args)...);
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker using SequenceBound<T>::SequenceBound;
74*6777b538SAndroid Build Coastguard Worker using SequenceBound<T>::operator=;
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker private:
77*6777b538SAndroid Build Coastguard Worker using SequenceBound<T>::emplace;
78*6777b538SAndroid Build Coastguard Worker };
79*6777b538SAndroid Build Coastguard Worker };
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker struct UniquePtrVariation {
82*6777b538SAndroid Build Coastguard Worker static constexpr bool kManagingTaskRunnerConstructsT = false;
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker template <typename T>
85*6777b538SAndroid Build Coastguard Worker struct Wrapper : public SequenceBound<std::unique_ptr<T>> {
86*6777b538SAndroid Build Coastguard Worker public:
87*6777b538SAndroid Build Coastguard Worker template <typename... Args>
Wrapperbase::__anon5d5b4e930111::UniquePtrVariation::Wrapper88*6777b538SAndroid Build Coastguard Worker explicit Wrapper(scoped_refptr<SequencedTaskRunner> task_runner,
89*6777b538SAndroid Build Coastguard Worker Args&&... args)
90*6777b538SAndroid Build Coastguard Worker : SequenceBound<std::unique_ptr<T>>(
91*6777b538SAndroid Build Coastguard Worker std::move(task_runner),
92*6777b538SAndroid Build Coastguard Worker std::make_unique<T>(std::forward<Args>(args)...)) {}
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker template <typename... Args>
WrappedEmplacebase::__anon5d5b4e930111::UniquePtrVariation::Wrapper95*6777b538SAndroid Build Coastguard Worker void WrappedEmplace(scoped_refptr<SequencedTaskRunner> task_runner,
96*6777b538SAndroid Build Coastguard Worker Args&&... args) {
97*6777b538SAndroid Build Coastguard Worker this->emplace(std::move(task_runner),
98*6777b538SAndroid Build Coastguard Worker std::make_unique<T>(std::forward<Args>(args)...));
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker using SequenceBound<std::unique_ptr<T>>::SequenceBound;
102*6777b538SAndroid Build Coastguard Worker using SequenceBound<std::unique_ptr<T>>::operator=;
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker private:
105*6777b538SAndroid Build Coastguard Worker using SequenceBound<std::unique_ptr<T>>::emplace;
106*6777b538SAndroid Build Coastguard Worker };
107*6777b538SAndroid Build Coastguard Worker };
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker // Helper macros since using the name directly is otherwise quite unwieldy.
110*6777b538SAndroid Build Coastguard Worker #define SEQUENCE_BOUND_T typename TypeParam::template Wrapper
111*6777b538SAndroid Build Coastguard Worker // Try to catch tests that inadvertently use SequenceBound<T> directly instead
112*6777b538SAndroid Build Coastguard Worker // of SEQUENCE_BOUND_T, as that bypasses the point of having a typed test.
113*6777b538SAndroid Build Coastguard Worker #define SequenceBound PleaseUseSequenceBoundT
114*6777b538SAndroid Build Coastguard Worker
115*6777b538SAndroid Build Coastguard Worker template <typename Variation>
116*6777b538SAndroid Build Coastguard Worker class SequenceBoundTest : public ::testing::Test {
117*6777b538SAndroid Build Coastguard Worker public:
TearDown()118*6777b538SAndroid Build Coastguard Worker void TearDown() override {
119*6777b538SAndroid Build Coastguard Worker // Make sure that any objects owned by `SequenceBound` have been destroyed
120*6777b538SAndroid Build Coastguard Worker // to avoid tripping leak detection.
121*6777b538SAndroid Build Coastguard Worker task_environment_.RunUntilIdle();
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker // Helper for tests that want to synchronize on a `SequenceBound` which has
125*6777b538SAndroid Build Coastguard Worker // already been `Reset()`: a null `SequenceBound` has no `SequencedTaskRunner`
126*6777b538SAndroid Build Coastguard Worker // associated with it, so the usual `FlushPostedTasksForTesting()` helper does
127*6777b538SAndroid Build Coastguard Worker // not work.
FlushPostedTasks()128*6777b538SAndroid Build Coastguard Worker void FlushPostedTasks() {
129*6777b538SAndroid Build Coastguard Worker RunLoop run_loop;
130*6777b538SAndroid Build Coastguard Worker background_task_runner_->PostTask(FROM_HERE, run_loop.QuitClosure());
131*6777b538SAndroid Build Coastguard Worker run_loop.Run();
132*6777b538SAndroid Build Coastguard Worker }
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker test::TaskEnvironment task_environment_;
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker // Task runner to use for SequenceBound's managed `T`.
137*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> background_task_runner_ =
138*6777b538SAndroid Build Coastguard Worker ThreadPool::CreateSequencedTaskRunner({});
139*6777b538SAndroid Build Coastguard Worker
140*6777b538SAndroid Build Coastguard Worker // Defined as part of the test fixture so that tests using `EventLogger` do
141*6777b538SAndroid Build Coastguard Worker // not need to explicitly synchronize on `Reset() to avoid use-after-frees;
142*6777b538SAndroid Build Coastguard Worker // instead, tests should rely on `TearDown()` to drain and run any
143*6777b538SAndroid Build Coastguard Worker // already-posted cleanup tasks.
144*6777b538SAndroid Build Coastguard Worker EventLogger logger_;
145*6777b538SAndroid Build Coastguard Worker };
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker using Variations = ::testing::Types<DirectVariation, UniquePtrVariation>;
148*6777b538SAndroid Build Coastguard Worker TYPED_TEST_SUITE(SequenceBoundTest, Variations);
149*6777b538SAndroid Build Coastguard Worker
150*6777b538SAndroid Build Coastguard Worker class Base {
151*6777b538SAndroid Build Coastguard Worker public:
Base(EventLogger & logger)152*6777b538SAndroid Build Coastguard Worker explicit Base(EventLogger& logger) : logger_(logger) {
153*6777b538SAndroid Build Coastguard Worker logger_->AddEvent("constructed Base");
154*6777b538SAndroid Build Coastguard Worker }
~Base()155*6777b538SAndroid Build Coastguard Worker virtual ~Base() { logger_->AddEvent("destroyed Base"); }
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker protected:
GetLogger()158*6777b538SAndroid Build Coastguard Worker EventLogger& GetLogger() { return *logger_; }
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker private:
161*6777b538SAndroid Build Coastguard Worker const raw_ref<EventLogger> logger_;
162*6777b538SAndroid Build Coastguard Worker };
163*6777b538SAndroid Build Coastguard Worker
164*6777b538SAndroid Build Coastguard Worker class Derived : public Base {
165*6777b538SAndroid Build Coastguard Worker public:
Derived(EventLogger & logger)166*6777b538SAndroid Build Coastguard Worker explicit Derived(EventLogger& logger) : Base(logger) {
167*6777b538SAndroid Build Coastguard Worker GetLogger().AddEvent("constructed Derived");
168*6777b538SAndroid Build Coastguard Worker }
169*6777b538SAndroid Build Coastguard Worker
~Derived()170*6777b538SAndroid Build Coastguard Worker ~Derived() override { GetLogger().AddEvent("destroyed Derived"); }
171*6777b538SAndroid Build Coastguard Worker
SetValue(int value)172*6777b538SAndroid Build Coastguard Worker void SetValue(int value) {
173*6777b538SAndroid Build Coastguard Worker GetLogger().AddEvent(StringPrintf("set Derived to %d", value));
174*6777b538SAndroid Build Coastguard Worker }
175*6777b538SAndroid Build Coastguard Worker };
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker class Leftmost {
178*6777b538SAndroid Build Coastguard Worker public:
Leftmost(EventLogger & logger)179*6777b538SAndroid Build Coastguard Worker explicit Leftmost(EventLogger& logger) : logger_(logger) {
180*6777b538SAndroid Build Coastguard Worker logger_->AddEvent("constructed Leftmost");
181*6777b538SAndroid Build Coastguard Worker }
~Leftmost()182*6777b538SAndroid Build Coastguard Worker virtual ~Leftmost() { logger_->AddEvent("destroyed Leftmost"); }
183*6777b538SAndroid Build Coastguard Worker
SetValue(int value)184*6777b538SAndroid Build Coastguard Worker void SetValue(int value) {
185*6777b538SAndroid Build Coastguard Worker logger_->AddEvent(StringPrintf("set Leftmost to %d", value));
186*6777b538SAndroid Build Coastguard Worker }
187*6777b538SAndroid Build Coastguard Worker
188*6777b538SAndroid Build Coastguard Worker private:
189*6777b538SAndroid Build Coastguard Worker const raw_ref<EventLogger> logger_;
190*6777b538SAndroid Build Coastguard Worker };
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker class Rightmost : public Base {
193*6777b538SAndroid Build Coastguard Worker public:
Rightmost(EventLogger & logger)194*6777b538SAndroid Build Coastguard Worker explicit Rightmost(EventLogger& logger) : Base(logger) {
195*6777b538SAndroid Build Coastguard Worker GetLogger().AddEvent("constructed Rightmost");
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker
~Rightmost()198*6777b538SAndroid Build Coastguard Worker ~Rightmost() override { GetLogger().AddEvent("destroyed Rightmost"); }
199*6777b538SAndroid Build Coastguard Worker
SetValue(int value)200*6777b538SAndroid Build Coastguard Worker void SetValue(int value) {
201*6777b538SAndroid Build Coastguard Worker GetLogger().AddEvent(StringPrintf("set Rightmost to %d", value));
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker };
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker class MultiplyDerived : public Leftmost, public Rightmost {
206*6777b538SAndroid Build Coastguard Worker public:
MultiplyDerived(EventLogger & logger)207*6777b538SAndroid Build Coastguard Worker explicit MultiplyDerived(EventLogger& logger)
208*6777b538SAndroid Build Coastguard Worker : Leftmost(logger), Rightmost(logger) {
209*6777b538SAndroid Build Coastguard Worker GetLogger().AddEvent("constructed MultiplyDerived");
210*6777b538SAndroid Build Coastguard Worker }
211*6777b538SAndroid Build Coastguard Worker
~MultiplyDerived()212*6777b538SAndroid Build Coastguard Worker ~MultiplyDerived() override {
213*6777b538SAndroid Build Coastguard Worker GetLogger().AddEvent("destroyed MultiplyDerived");
214*6777b538SAndroid Build Coastguard Worker }
215*6777b538SAndroid Build Coastguard Worker };
216*6777b538SAndroid Build Coastguard Worker
217*6777b538SAndroid Build Coastguard Worker class BoxedValue {
218*6777b538SAndroid Build Coastguard Worker public:
BoxedValue(int initial_value,EventLogger * logger=nullptr)219*6777b538SAndroid Build Coastguard Worker explicit BoxedValue(int initial_value, EventLogger* logger = nullptr)
220*6777b538SAndroid Build Coastguard Worker : logger_(logger), value_(initial_value) {
221*6777b538SAndroid Build Coastguard Worker sequence_checker_.DetachFromSequence();
222*6777b538SAndroid Build Coastguard Worker AddEventIfNeeded(StringPrintf("constructed BoxedValue = %d", value_));
223*6777b538SAndroid Build Coastguard Worker }
224*6777b538SAndroid Build Coastguard Worker
225*6777b538SAndroid Build Coastguard Worker BoxedValue(const BoxedValue&) = delete;
226*6777b538SAndroid Build Coastguard Worker BoxedValue& operator=(const BoxedValue&) = delete;
227*6777b538SAndroid Build Coastguard Worker
~BoxedValue()228*6777b538SAndroid Build Coastguard Worker ~BoxedValue() {
229*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
230*6777b538SAndroid Build Coastguard Worker AddEventIfNeeded(StringPrintf("destroyed BoxedValue = %d", value_));
231*6777b538SAndroid Build Coastguard Worker if (destruction_callback_)
232*6777b538SAndroid Build Coastguard Worker std::move(destruction_callback_).Run();
233*6777b538SAndroid Build Coastguard Worker }
234*6777b538SAndroid Build Coastguard Worker
set_destruction_callback(OnceClosure callback)235*6777b538SAndroid Build Coastguard Worker void set_destruction_callback(OnceClosure callback) {
236*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
237*6777b538SAndroid Build Coastguard Worker destruction_callback_ = std::move(callback);
238*6777b538SAndroid Build Coastguard Worker }
239*6777b538SAndroid Build Coastguard Worker
value() const240*6777b538SAndroid Build Coastguard Worker int value() const {
241*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
242*6777b538SAndroid Build Coastguard Worker AddEventIfNeeded(StringPrintf("accessed BoxedValue = %d", value_));
243*6777b538SAndroid Build Coastguard Worker return value_;
244*6777b538SAndroid Build Coastguard Worker }
set_value(int value)245*6777b538SAndroid Build Coastguard Worker void set_value(int value) {
246*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
247*6777b538SAndroid Build Coastguard Worker AddEventIfNeeded(
248*6777b538SAndroid Build Coastguard Worker StringPrintf("updated BoxedValue from %d to %d", value_, value));
249*6777b538SAndroid Build Coastguard Worker value_ = value;
250*6777b538SAndroid Build Coastguard Worker }
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker private:
AddEventIfNeeded(std::string_view event) const253*6777b538SAndroid Build Coastguard Worker void AddEventIfNeeded(std::string_view event) const {
254*6777b538SAndroid Build Coastguard Worker if (logger_) {
255*6777b538SAndroid Build Coastguard Worker logger_->AddEvent(event);
256*6777b538SAndroid Build Coastguard Worker }
257*6777b538SAndroid Build Coastguard Worker }
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker SequenceChecker sequence_checker_;
260*6777b538SAndroid Build Coastguard Worker
261*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<EventLogger> logger_ = nullptr;
262*6777b538SAndroid Build Coastguard Worker
263*6777b538SAndroid Build Coastguard Worker int value_ = 0;
264*6777b538SAndroid Build Coastguard Worker OnceClosure destruction_callback_;
265*6777b538SAndroid Build Coastguard Worker };
266*6777b538SAndroid Build Coastguard Worker
267*6777b538SAndroid Build Coastguard Worker // Smoke test that all interactions with the wrapped object are posted to the
268*6777b538SAndroid Build Coastguard Worker // correct task runner.
269*6777b538SAndroid Build Coastguard Worker class SequenceValidator {
270*6777b538SAndroid Build Coastguard Worker public:
SequenceValidator(scoped_refptr<SequencedTaskRunner> task_runner,bool constructs_on_managing_task_runner)271*6777b538SAndroid Build Coastguard Worker explicit SequenceValidator(scoped_refptr<SequencedTaskRunner> task_runner,
272*6777b538SAndroid Build Coastguard Worker bool constructs_on_managing_task_runner)
273*6777b538SAndroid Build Coastguard Worker : task_runner_(std::move(task_runner)) {
274*6777b538SAndroid Build Coastguard Worker if (constructs_on_managing_task_runner) {
275*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence());
276*6777b538SAndroid Build Coastguard Worker }
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker
~SequenceValidator()279*6777b538SAndroid Build Coastguard Worker ~SequenceValidator() {
280*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence());
281*6777b538SAndroid Build Coastguard Worker }
282*6777b538SAndroid Build Coastguard Worker
ReturnsVoid() const283*6777b538SAndroid Build Coastguard Worker void ReturnsVoid() const {
284*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence());
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker
ReturnsVoidMutable()287*6777b538SAndroid Build Coastguard Worker void ReturnsVoidMutable() {
288*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence());
289*6777b538SAndroid Build Coastguard Worker }
290*6777b538SAndroid Build Coastguard Worker
ReturnsInt() const291*6777b538SAndroid Build Coastguard Worker int ReturnsInt() const {
292*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence());
293*6777b538SAndroid Build Coastguard Worker return 0;
294*6777b538SAndroid Build Coastguard Worker }
295*6777b538SAndroid Build Coastguard Worker
ReturnsIntMutable()296*6777b538SAndroid Build Coastguard Worker int ReturnsIntMutable() {
297*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence());
298*6777b538SAndroid Build Coastguard Worker return 0;
299*6777b538SAndroid Build Coastguard Worker }
300*6777b538SAndroid Build Coastguard Worker
301*6777b538SAndroid Build Coastguard Worker private:
302*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner_;
303*6777b538SAndroid Build Coastguard Worker };
304*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,SequenceValidation)305*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, SequenceValidation) {
306*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<SequenceValidator> validator(
307*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, this->background_task_runner_,
308*6777b538SAndroid Build Coastguard Worker TypeParam::kManagingTaskRunnerConstructsT);
309*6777b538SAndroid Build Coastguard Worker validator.AsyncCall(&SequenceValidator::ReturnsVoid);
310*6777b538SAndroid Build Coastguard Worker validator.AsyncCall(&SequenceValidator::ReturnsVoidMutable);
311*6777b538SAndroid Build Coastguard Worker validator.AsyncCall(&SequenceValidator::ReturnsInt).Then(BindOnce([](int) {
312*6777b538SAndroid Build Coastguard Worker }));
313*6777b538SAndroid Build Coastguard Worker validator.AsyncCall(&SequenceValidator::ReturnsIntMutable)
314*6777b538SAndroid Build Coastguard Worker .Then(BindOnce([](int) {}));
315*6777b538SAndroid Build Coastguard Worker validator.AsyncCall(IgnoreResult(&SequenceValidator::ReturnsInt));
316*6777b538SAndroid Build Coastguard Worker validator.AsyncCall(IgnoreResult(&SequenceValidator::ReturnsIntMutable));
317*6777b538SAndroid Build Coastguard Worker validator.WrappedEmplace(this->background_task_runner_,
318*6777b538SAndroid Build Coastguard Worker this->background_task_runner_,
319*6777b538SAndroid Build Coastguard Worker TypeParam::kManagingTaskRunnerConstructsT);
320*6777b538SAndroid Build Coastguard Worker validator.PostTaskWithThisObject(BindLambdaForTesting(
321*6777b538SAndroid Build Coastguard Worker [](const SequenceValidator& v) { v.ReturnsVoid(); }));
322*6777b538SAndroid Build Coastguard Worker validator.PostTaskWithThisObject(BindLambdaForTesting(
323*6777b538SAndroid Build Coastguard Worker [](SequenceValidator* v) { v->ReturnsVoidMutable(); }));
324*6777b538SAndroid Build Coastguard Worker validator.Reset();
325*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
326*6777b538SAndroid Build Coastguard Worker }
327*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,Basic)328*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, Basic) {
329*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_, 0,
330*6777b538SAndroid Build Coastguard Worker &this->logger_);
331*6777b538SAndroid Build Coastguard Worker // Construction of `BoxedValue` may be posted to `background_task_runner_`,
332*6777b538SAndroid Build Coastguard Worker // but the `SequenceBound` itself should immediately be treated as valid /
333*6777b538SAndroid Build Coastguard Worker // non-null.
334*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(value.is_null());
335*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(value);
336*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
337*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
338*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed BoxedValue = 0"));
339*6777b538SAndroid Build Coastguard Worker
340*6777b538SAndroid Build Coastguard Worker value.AsyncCall(&BoxedValue::set_value).WithArgs(66);
341*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
342*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
343*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("updated BoxedValue from 0 to 66"));
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker // Destruction of `BoxedValue` may be posted to `background_task_runner_`, but
346*6777b538SAndroid Build Coastguard Worker // the `SequenceBound` itself should immediately be treated as valid /
347*6777b538SAndroid Build Coastguard Worker // non-null.
348*6777b538SAndroid Build Coastguard Worker value.Reset();
349*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(value.is_null());
350*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(value);
351*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
352*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
353*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("destroyed BoxedValue = 66"));
354*6777b538SAndroid Build Coastguard Worker }
355*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,ConstructAndImmediateAsyncCall)356*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, ConstructAndImmediateAsyncCall) {
357*6777b538SAndroid Build Coastguard Worker // Calling `AsyncCall` immediately after construction should always work.
358*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_, 0,
359*6777b538SAndroid Build Coastguard Worker &this->logger_);
360*6777b538SAndroid Build Coastguard Worker value.AsyncCall(&BoxedValue::set_value).WithArgs(8);
361*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
362*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
363*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed BoxedValue = 0",
364*6777b538SAndroid Build Coastguard Worker "updated BoxedValue from 0 to 8"));
365*6777b538SAndroid Build Coastguard Worker }
366*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveConstruction)367*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveConstruction) {
368*6777b538SAndroid Build Coastguard Worker // std::ref() is required here: internally, the async work is bound into the
369*6777b538SAndroid Build Coastguard Worker // standard base callback infrastructure, which requires the explicit use of
370*6777b538SAndroid Build Coastguard Worker // `std::cref()` and `std::ref()` when passing by reference.
371*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Derived> derived_old(this->background_task_runner_,
372*6777b538SAndroid Build Coastguard Worker std::ref(this->logger_));
373*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Derived> derived_new = std::move(derived_old);
374*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
375*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(derived_old.is_null());
376*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(derived_new.is_null());
377*6777b538SAndroid Build Coastguard Worker derived_new.Reset();
378*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
379*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
380*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed Base", "constructed Derived",
381*6777b538SAndroid Build Coastguard Worker "destroyed Derived", "destroyed Base"));
382*6777b538SAndroid Build Coastguard Worker }
383*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveConstructionUpcastsToBase)384*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveConstructionUpcastsToBase) {
385*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Derived> derived(this->background_task_runner_,
386*6777b538SAndroid Build Coastguard Worker std::ref(this->logger_));
387*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Base> base = std::move(derived);
388*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
389*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(derived.is_null());
390*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base.is_null());
391*6777b538SAndroid Build Coastguard Worker
392*6777b538SAndroid Build Coastguard Worker // The original `Derived` object is now owned by `SequencedBound<Base>`; make
393*6777b538SAndroid Build Coastguard Worker // sure `~Derived()` still runs when it is reset.
394*6777b538SAndroid Build Coastguard Worker base.Reset();
395*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
396*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
397*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed Base", "constructed Derived",
398*6777b538SAndroid Build Coastguard Worker "destroyed Derived", "destroyed Base"));
399*6777b538SAndroid Build Coastguard Worker }
400*6777b538SAndroid Build Coastguard Worker
401*6777b538SAndroid Build Coastguard Worker // Classes with multiple-derived bases may need pointer adjustments when
402*6777b538SAndroid Build Coastguard Worker // upcasting. These tests rely on sanitizers to catch potential mistakes.
TYPED_TEST(SequenceBoundTest,MoveConstructionUpcastsToLeftmost)403*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveConstructionUpcastsToLeftmost) {
404*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<MultiplyDerived> multiply_derived(
405*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, std::ref(this->logger_));
406*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Leftmost> leftmost_base = std::move(multiply_derived);
407*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
408*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(multiply_derived.is_null());
409*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(leftmost_base.is_null());
410*6777b538SAndroid Build Coastguard Worker
411*6777b538SAndroid Build Coastguard Worker // The original `MultiplyDerived` object is now owned by
412*6777b538SAndroid Build Coastguard Worker // `SequencedBound<Leftmost>`; make sure all the expected destructors
413*6777b538SAndroid Build Coastguard Worker // still run when it is reset.
414*6777b538SAndroid Build Coastguard Worker leftmost_base.Reset();
415*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
416*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(
417*6777b538SAndroid Build Coastguard Worker this->logger_.TakeEvents(),
418*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre(
419*6777b538SAndroid Build Coastguard Worker "constructed Leftmost", "constructed Base", "constructed Rightmost",
420*6777b538SAndroid Build Coastguard Worker "constructed MultiplyDerived", "destroyed MultiplyDerived",
421*6777b538SAndroid Build Coastguard Worker "destroyed Rightmost", "destroyed Base", "destroyed Leftmost"));
422*6777b538SAndroid Build Coastguard Worker }
423*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveConstructionUpcastsToRightmost)424*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveConstructionUpcastsToRightmost) {
425*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<MultiplyDerived> multiply_derived(
426*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, std::ref(this->logger_));
427*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Rightmost> rightmost_base = std::move(multiply_derived);
428*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
429*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(multiply_derived.is_null());
430*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(rightmost_base.is_null());
431*6777b538SAndroid Build Coastguard Worker
432*6777b538SAndroid Build Coastguard Worker // The original `MultiplyDerived` object is now owned by
433*6777b538SAndroid Build Coastguard Worker // `SequencedBound<Rightmost>`; make sure all the expected destructors
434*6777b538SAndroid Build Coastguard Worker // still run when it is reset.
435*6777b538SAndroid Build Coastguard Worker rightmost_base.Reset();
436*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
437*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(
438*6777b538SAndroid Build Coastguard Worker this->logger_.TakeEvents(),
439*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre(
440*6777b538SAndroid Build Coastguard Worker "constructed Leftmost", "constructed Base", "constructed Rightmost",
441*6777b538SAndroid Build Coastguard Worker "constructed MultiplyDerived", "destroyed MultiplyDerived",
442*6777b538SAndroid Build Coastguard Worker "destroyed Rightmost", "destroyed Base", "destroyed Leftmost"));
443*6777b538SAndroid Build Coastguard Worker }
444*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveAssignment)445*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveAssignment) {
446*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Derived> derived_old(this->background_task_runner_,
447*6777b538SAndroid Build Coastguard Worker std::ref(this->logger_));
448*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Derived> derived_new;
449*6777b538SAndroid Build Coastguard Worker
450*6777b538SAndroid Build Coastguard Worker derived_new = std::move(derived_old);
451*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
452*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(derived_old.is_null());
453*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(derived_new.is_null());
454*6777b538SAndroid Build Coastguard Worker
455*6777b538SAndroid Build Coastguard Worker // Note that this explicitly avoids using `Reset()` as a basic test that
456*6777b538SAndroid Build Coastguard Worker // assignment resets any previously-owned object.
457*6777b538SAndroid Build Coastguard Worker derived_new = SEQUENCE_BOUND_T<Derived>();
458*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
459*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
460*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed Base", "constructed Derived",
461*6777b538SAndroid Build Coastguard Worker "destroyed Derived", "destroyed Base"));
462*6777b538SAndroid Build Coastguard Worker }
463*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveAssignmentUpcastsToBase)464*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveAssignmentUpcastsToBase) {
465*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Derived> derived(this->background_task_runner_,
466*6777b538SAndroid Build Coastguard Worker std::ref(this->logger_));
467*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Base> base;
468*6777b538SAndroid Build Coastguard Worker
469*6777b538SAndroid Build Coastguard Worker base = std::move(derived);
470*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
471*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(derived.is_null());
472*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(base.is_null());
473*6777b538SAndroid Build Coastguard Worker
474*6777b538SAndroid Build Coastguard Worker // The original `Derived` object is now owned by `SequencedBound<Base>`; make
475*6777b538SAndroid Build Coastguard Worker // sure `~Derived()` still runs when it is reset.
476*6777b538SAndroid Build Coastguard Worker base.Reset();
477*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
478*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
479*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed Base", "constructed Derived",
480*6777b538SAndroid Build Coastguard Worker "destroyed Derived", "destroyed Base"));
481*6777b538SAndroid Build Coastguard Worker }
482*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveAssignmentUpcastsToLeftmost)483*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveAssignmentUpcastsToLeftmost) {
484*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<MultiplyDerived> multiply_derived(
485*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, std::ref(this->logger_));
486*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Leftmost> leftmost_base;
487*6777b538SAndroid Build Coastguard Worker
488*6777b538SAndroid Build Coastguard Worker leftmost_base = std::move(multiply_derived);
489*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
490*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(multiply_derived.is_null());
491*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(leftmost_base.is_null());
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard Worker // The original `MultiplyDerived` object is now owned by
494*6777b538SAndroid Build Coastguard Worker // `SequencedBound<Leftmost>`; make sure all the expected destructors
495*6777b538SAndroid Build Coastguard Worker // still run when it is reset.
496*6777b538SAndroid Build Coastguard Worker leftmost_base.Reset();
497*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
498*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(
499*6777b538SAndroid Build Coastguard Worker this->logger_.TakeEvents(),
500*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre(
501*6777b538SAndroid Build Coastguard Worker "constructed Leftmost", "constructed Base", "constructed Rightmost",
502*6777b538SAndroid Build Coastguard Worker "constructed MultiplyDerived", "destroyed MultiplyDerived",
503*6777b538SAndroid Build Coastguard Worker "destroyed Rightmost", "destroyed Base", "destroyed Leftmost"));
504*6777b538SAndroid Build Coastguard Worker }
505*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveAssignmentUpcastsToRightmost)506*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveAssignmentUpcastsToRightmost) {
507*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<MultiplyDerived> multiply_derived(
508*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, std::ref(this->logger_));
509*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<Rightmost> rightmost_base;
510*6777b538SAndroid Build Coastguard Worker
511*6777b538SAndroid Build Coastguard Worker rightmost_base = std::move(multiply_derived);
512*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(bugprone-use-after-move)
513*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(multiply_derived.is_null());
514*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(rightmost_base.is_null());
515*6777b538SAndroid Build Coastguard Worker
516*6777b538SAndroid Build Coastguard Worker // The original `MultiplyDerived` object is now owned by
517*6777b538SAndroid Build Coastguard Worker // `SequencedBound<Rightmost>`; make sure all the expected destructors
518*6777b538SAndroid Build Coastguard Worker // still run when it is reset.
519*6777b538SAndroid Build Coastguard Worker rightmost_base.Reset();
520*6777b538SAndroid Build Coastguard Worker this->FlushPostedTasks();
521*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(
522*6777b538SAndroid Build Coastguard Worker this->logger_.TakeEvents(),
523*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre(
524*6777b538SAndroid Build Coastguard Worker "constructed Leftmost", "constructed Base", "constructed Rightmost",
525*6777b538SAndroid Build Coastguard Worker "constructed MultiplyDerived", "destroyed MultiplyDerived",
526*6777b538SAndroid Build Coastguard Worker "destroyed Rightmost", "destroyed Base", "destroyed Leftmost"));
527*6777b538SAndroid Build Coastguard Worker }
528*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallLeftmost)529*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallLeftmost) {
530*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<MultiplyDerived> multiply_derived(
531*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, std::ref(this->logger_));
532*6777b538SAndroid Build Coastguard Worker multiply_derived.AsyncCall(&Leftmost::SetValue).WithArgs(3);
533*6777b538SAndroid Build Coastguard Worker multiply_derived.FlushPostedTasksForTesting();
534*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
535*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed Leftmost", "constructed Base",
536*6777b538SAndroid Build Coastguard Worker "constructed Rightmost",
537*6777b538SAndroid Build Coastguard Worker "constructed MultiplyDerived",
538*6777b538SAndroid Build Coastguard Worker "set Leftmost to 3"));
539*6777b538SAndroid Build Coastguard Worker }
540*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallRightmost)541*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallRightmost) {
542*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<MultiplyDerived> multiply_derived(
543*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, std::ref(this->logger_));
544*6777b538SAndroid Build Coastguard Worker multiply_derived.AsyncCall(&Rightmost::SetValue).WithArgs(3);
545*6777b538SAndroid Build Coastguard Worker multiply_derived.FlushPostedTasksForTesting();
546*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
547*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed Leftmost", "constructed Base",
548*6777b538SAndroid Build Coastguard Worker "constructed Rightmost",
549*6777b538SAndroid Build Coastguard Worker "constructed MultiplyDerived",
550*6777b538SAndroid Build Coastguard Worker "set Rightmost to 3"));
551*6777b538SAndroid Build Coastguard Worker }
552*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveConstructionFromNull)553*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveConstructionFromNull) {
554*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value1;
555*6777b538SAndroid Build Coastguard Worker // Should not crash.
556*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value2(std::move(value1));
557*6777b538SAndroid Build Coastguard Worker }
558*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveAssignmentFromNull)559*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveAssignmentFromNull) {
560*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value1;
561*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value2;
562*6777b538SAndroid Build Coastguard Worker // Should not crash.
563*6777b538SAndroid Build Coastguard Worker value2 = std::move(value1);
564*6777b538SAndroid Build Coastguard Worker }
565*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,MoveAssignmentFromSelf)566*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, MoveAssignmentFromSelf) {
567*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value;
568*6777b538SAndroid Build Coastguard Worker // Cheat to avoid clang self-move warning.
569*6777b538SAndroid Build Coastguard Worker auto& value2 = value;
570*6777b538SAndroid Build Coastguard Worker // Should not crash.
571*6777b538SAndroid Build Coastguard Worker value2 = std::move(value);
572*6777b538SAndroid Build Coastguard Worker }
573*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,ResetNullSequenceBound)574*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, ResetNullSequenceBound) {
575*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value;
576*6777b538SAndroid Build Coastguard Worker // Should not crash.
577*6777b538SAndroid Build Coastguard Worker value.Reset();
578*6777b538SAndroid Build Coastguard Worker }
579*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,ConstructWithLvalue)580*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, ConstructWithLvalue) {
581*6777b538SAndroid Build Coastguard Worker int lvalue = 99;
582*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_, lvalue,
583*6777b538SAndroid Build Coastguard Worker &this->logger_);
584*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
585*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
586*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed BoxedValue = 99"));
587*6777b538SAndroid Build Coastguard Worker }
588*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,PostTaskWithThisObject)589*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, PostTaskWithThisObject) {
590*6777b538SAndroid Build Coastguard Worker constexpr int kTestValue1 = 42;
591*6777b538SAndroid Build Coastguard Worker constexpr int kTestValue2 = 42;
592*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_,
593*6777b538SAndroid Build Coastguard Worker kTestValue1);
594*6777b538SAndroid Build Coastguard Worker value.PostTaskWithThisObject(BindLambdaForTesting(
595*6777b538SAndroid Build Coastguard Worker [&](const BoxedValue& v) { EXPECT_EQ(kTestValue1, v.value()); }));
596*6777b538SAndroid Build Coastguard Worker value.PostTaskWithThisObject(
597*6777b538SAndroid Build Coastguard Worker BindLambdaForTesting([&](BoxedValue* v) { v->set_value(kTestValue2); }));
598*6777b538SAndroid Build Coastguard Worker value.PostTaskWithThisObject(BindLambdaForTesting(
599*6777b538SAndroid Build Coastguard Worker [&](const BoxedValue& v) { EXPECT_EQ(kTestValue2, v.value()); }));
600*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
601*6777b538SAndroid Build Coastguard Worker }
602*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,SynchronouslyResetForTest)603*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, SynchronouslyResetForTest) {
604*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_, 0);
605*6777b538SAndroid Build Coastguard Worker
606*6777b538SAndroid Build Coastguard Worker bool destroyed = false;
607*6777b538SAndroid Build Coastguard Worker value.AsyncCall(&BoxedValue::set_destruction_callback)
608*6777b538SAndroid Build Coastguard Worker .WithArgs(BindLambdaForTesting([&] { destroyed = true; }));
609*6777b538SAndroid Build Coastguard Worker
610*6777b538SAndroid Build Coastguard Worker value.SynchronouslyResetForTest();
611*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(destroyed);
612*6777b538SAndroid Build Coastguard Worker }
613*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,FlushPostedTasksForTesting)614*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, FlushPostedTasksForTesting) {
615*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_, 0,
616*6777b538SAndroid Build Coastguard Worker &this->logger_);
617*6777b538SAndroid Build Coastguard Worker
618*6777b538SAndroid Build Coastguard Worker value.AsyncCall(&BoxedValue::set_value).WithArgs(42);
619*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
620*6777b538SAndroid Build Coastguard Worker
621*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
622*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre("constructed BoxedValue = 0",
623*6777b538SAndroid Build Coastguard Worker "updated BoxedValue from 0 to 42"));
624*6777b538SAndroid Build Coastguard Worker }
625*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,SmallObject)626*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, SmallObject) {
627*6777b538SAndroid Build Coastguard Worker class EmptyClass {};
628*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<EmptyClass> value(this->background_task_runner_);
629*6777b538SAndroid Build Coastguard Worker // Test passes if SequenceBound constructor does not crash in AlignedAlloc().
630*6777b538SAndroid Build Coastguard Worker }
631*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,SelfMoveAssign)632*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, SelfMoveAssign) {
633*6777b538SAndroid Build Coastguard Worker class EmptyClass {};
634*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<EmptyClass> value(this->background_task_runner_);
635*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(value.is_null());
636*6777b538SAndroid Build Coastguard Worker // Clang has a warning for self-move, so be clever.
637*6777b538SAndroid Build Coastguard Worker auto& actually_the_same_value = value;
638*6777b538SAndroid Build Coastguard Worker value = std::move(actually_the_same_value);
639*6777b538SAndroid Build Coastguard Worker // Note: in general, moved-from objects are in a valid but undefined state.
640*6777b538SAndroid Build Coastguard Worker // This is merely a test that self-move doesn't result in something bad
641*6777b538SAndroid Build Coastguard Worker // happening; this is not an assertion that self-move will always have this
642*6777b538SAndroid Build Coastguard Worker // behavior.
643*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(value.is_null());
644*6777b538SAndroid Build Coastguard Worker }
645*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,Emplace)646*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, Emplace) {
647*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value;
648*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(value.is_null());
649*6777b538SAndroid Build Coastguard Worker value.WrappedEmplace(this->background_task_runner_, 8);
650*6777b538SAndroid Build Coastguard Worker value.AsyncCall(&BoxedValue::value)
651*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting(
652*6777b538SAndroid Build Coastguard Worker [&](int actual_value) { EXPECT_EQ(8, actual_value); }));
653*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
654*6777b538SAndroid Build Coastguard Worker }
655*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,EmplaceOverExisting)656*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, EmplaceOverExisting) {
657*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(this->background_task_runner_, 8,
658*6777b538SAndroid Build Coastguard Worker &this->logger_);
659*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(value.is_null());
660*6777b538SAndroid Build Coastguard Worker value.WrappedEmplace(this->background_task_runner_, 9, &this->logger_);
661*6777b538SAndroid Build Coastguard Worker value.AsyncCall(&BoxedValue::value)
662*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting(
663*6777b538SAndroid Build Coastguard Worker [&](int actual_value) { EXPECT_EQ(9, actual_value); }));
664*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
665*6777b538SAndroid Build Coastguard Worker
666*6777b538SAndroid Build Coastguard Worker if constexpr (TypeParam::kManagingTaskRunnerConstructsT) {
667*6777b538SAndroid Build Coastguard Worker // Both the replaced `BoxedValue` and the current `BoxedValue` should
668*6777b538SAndroid Build Coastguard Worker // live on the same sequence: make sure the replaced `BoxedValue` was
669*6777b538SAndroid Build Coastguard Worker // destroyed before the current `BoxedValue` was constructed.
670*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
671*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre(
672*6777b538SAndroid Build Coastguard Worker "constructed BoxedValue = 8", "destroyed BoxedValue = 8",
673*6777b538SAndroid Build Coastguard Worker "constructed BoxedValue = 9", "accessed BoxedValue = 9"));
674*6777b538SAndroid Build Coastguard Worker } else {
675*6777b538SAndroid Build Coastguard Worker // When `SequenceBound` manages a `std::unique_ptr<T>`, `T` is constructed
676*6777b538SAndroid Build Coastguard Worker // on the current sequence so construction of the new managed instance will
677*6777b538SAndroid Build Coastguard Worker // happen before the previously-managed instance is destroyed on the
678*6777b538SAndroid Build Coastguard Worker // managing task runner.
679*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(this->logger_.TakeEvents(),
680*6777b538SAndroid Build Coastguard Worker ::testing::ElementsAre(
681*6777b538SAndroid Build Coastguard Worker "constructed BoxedValue = 8", "constructed BoxedValue = 9",
682*6777b538SAndroid Build Coastguard Worker "destroyed BoxedValue = 8", "accessed BoxedValue = 9"));
683*6777b538SAndroid Build Coastguard Worker }
684*6777b538SAndroid Build Coastguard Worker }
685*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,EmplaceOverExistingWithTaskRunnerSwap)686*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, EmplaceOverExistingWithTaskRunnerSwap) {
687*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> another_task_runner =
688*6777b538SAndroid Build Coastguard Worker ThreadPool::CreateSequencedTaskRunner({});
689*6777b538SAndroid Build Coastguard Worker // No `EventLogger` here since destruction of the old `BoxedValue` and
690*6777b538SAndroid Build Coastguard Worker // construction of the new `BoxedValue` take place on different sequences and
691*6777b538SAndroid Build Coastguard Worker // can arbitrarily race.
692*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<BoxedValue> value(another_task_runner, 8);
693*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(value.is_null());
694*6777b538SAndroid Build Coastguard Worker value.WrappedEmplace(this->background_task_runner_, 9);
695*6777b538SAndroid Build Coastguard Worker {
696*6777b538SAndroid Build Coastguard Worker value.PostTaskWithThisObject(BindLambdaForTesting(
697*6777b538SAndroid Build Coastguard Worker [another_task_runner,
698*6777b538SAndroid Build Coastguard Worker background_task_runner =
699*6777b538SAndroid Build Coastguard Worker this->background_task_runner_](const BoxedValue& boxed_value) {
700*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(another_task_runner->RunsTasksInCurrentSequence());
701*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(background_task_runner->RunsTasksInCurrentSequence());
702*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(9, boxed_value.value());
703*6777b538SAndroid Build Coastguard Worker }));
704*6777b538SAndroid Build Coastguard Worker value.FlushPostedTasksForTesting();
705*6777b538SAndroid Build Coastguard Worker }
706*6777b538SAndroid Build Coastguard Worker }
707*6777b538SAndroid Build Coastguard Worker
708*6777b538SAndroid Build Coastguard Worker namespace {
709*6777b538SAndroid Build Coastguard Worker
710*6777b538SAndroid Build Coastguard Worker class NoArgsVoidReturn {
711*6777b538SAndroid Build Coastguard Worker public:
Method()712*6777b538SAndroid Build Coastguard Worker void Method() {
713*6777b538SAndroid Build Coastguard Worker if (loop_) {
714*6777b538SAndroid Build Coastguard Worker loop_->Quit();
715*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
716*6777b538SAndroid Build Coastguard Worker }
717*6777b538SAndroid Build Coastguard Worker }
ConstMethod() const718*6777b538SAndroid Build Coastguard Worker void ConstMethod() const {
719*6777b538SAndroid Build Coastguard Worker if (loop_) {
720*6777b538SAndroid Build Coastguard Worker loop_->Quit();
721*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
722*6777b538SAndroid Build Coastguard Worker }
723*6777b538SAndroid Build Coastguard Worker }
724*6777b538SAndroid Build Coastguard Worker
set_loop(RunLoop * loop)725*6777b538SAndroid Build Coastguard Worker void set_loop(RunLoop* loop) { loop_ = loop; }
726*6777b538SAndroid Build Coastguard Worker
727*6777b538SAndroid Build Coastguard Worker private:
728*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<RunLoop> loop_ = nullptr;
729*6777b538SAndroid Build Coastguard Worker };
730*6777b538SAndroid Build Coastguard Worker
731*6777b538SAndroid Build Coastguard Worker class NoArgsIntReturn {
732*6777b538SAndroid Build Coastguard Worker public:
Method()733*6777b538SAndroid Build Coastguard Worker int Method() { return 123; }
ConstMethod() const734*6777b538SAndroid Build Coastguard Worker int ConstMethod() const { return 456; }
735*6777b538SAndroid Build Coastguard Worker };
736*6777b538SAndroid Build Coastguard Worker
737*6777b538SAndroid Build Coastguard Worker class IntArgVoidReturn {
738*6777b538SAndroid Build Coastguard Worker public:
IntArgVoidReturn(int * method_called_with,int * const_method_called_with)739*6777b538SAndroid Build Coastguard Worker IntArgVoidReturn(int* method_called_with, int* const_method_called_with)
740*6777b538SAndroid Build Coastguard Worker : method_called_with_(method_called_with),
741*6777b538SAndroid Build Coastguard Worker const_method_called_with_(const_method_called_with) {}
742*6777b538SAndroid Build Coastguard Worker
Method(int x)743*6777b538SAndroid Build Coastguard Worker void Method(int x) {
744*6777b538SAndroid Build Coastguard Worker *method_called_with_ = x;
745*6777b538SAndroid Build Coastguard Worker method_called_with_ = nullptr;
746*6777b538SAndroid Build Coastguard Worker if (loop_) {
747*6777b538SAndroid Build Coastguard Worker loop_->Quit();
748*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
749*6777b538SAndroid Build Coastguard Worker }
750*6777b538SAndroid Build Coastguard Worker }
ConstMethod(int x) const751*6777b538SAndroid Build Coastguard Worker void ConstMethod(int x) const {
752*6777b538SAndroid Build Coastguard Worker *const_method_called_with_ = x;
753*6777b538SAndroid Build Coastguard Worker const_method_called_with_ = nullptr;
754*6777b538SAndroid Build Coastguard Worker if (loop_) {
755*6777b538SAndroid Build Coastguard Worker loop_->Quit();
756*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
757*6777b538SAndroid Build Coastguard Worker }
758*6777b538SAndroid Build Coastguard Worker }
759*6777b538SAndroid Build Coastguard Worker
set_loop(RunLoop * loop)760*6777b538SAndroid Build Coastguard Worker void set_loop(RunLoop* loop) { loop_ = loop; }
761*6777b538SAndroid Build Coastguard Worker
762*6777b538SAndroid Build Coastguard Worker private:
763*6777b538SAndroid Build Coastguard Worker raw_ptr<int> method_called_with_;
764*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<int> const_method_called_with_;
765*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<RunLoop> loop_ = nullptr;
766*6777b538SAndroid Build Coastguard Worker };
767*6777b538SAndroid Build Coastguard Worker
768*6777b538SAndroid Build Coastguard Worker class IntArgIntReturn {
769*6777b538SAndroid Build Coastguard Worker public:
Method(int x)770*6777b538SAndroid Build Coastguard Worker int Method(int x) { return -x; }
ConstMethod(int x) const771*6777b538SAndroid Build Coastguard Worker int ConstMethod(int x) const { return -x; }
772*6777b538SAndroid Build Coastguard Worker };
773*6777b538SAndroid Build Coastguard Worker
774*6777b538SAndroid Build Coastguard Worker } // namespace
775*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallNoArgsNoThen)776*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallNoArgsNoThen) {
777*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<NoArgsVoidReturn> s(this->background_task_runner_);
778*6777b538SAndroid Build Coastguard Worker
779*6777b538SAndroid Build Coastguard Worker {
780*6777b538SAndroid Build Coastguard Worker RunLoop loop;
781*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::set_loop).WithArgs(&loop);
782*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::Method);
783*6777b538SAndroid Build Coastguard Worker loop.Run();
784*6777b538SAndroid Build Coastguard Worker }
785*6777b538SAndroid Build Coastguard Worker
786*6777b538SAndroid Build Coastguard Worker {
787*6777b538SAndroid Build Coastguard Worker RunLoop loop;
788*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::set_loop).WithArgs(&loop);
789*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::ConstMethod);
790*6777b538SAndroid Build Coastguard Worker loop.Run();
791*6777b538SAndroid Build Coastguard Worker }
792*6777b538SAndroid Build Coastguard Worker }
793*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallIntArgNoThen)794*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallIntArgNoThen) {
795*6777b538SAndroid Build Coastguard Worker int method_called_with = 0;
796*6777b538SAndroid Build Coastguard Worker int const_method_called_with = 0;
797*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IntArgVoidReturn> s(this->background_task_runner_,
798*6777b538SAndroid Build Coastguard Worker &method_called_with,
799*6777b538SAndroid Build Coastguard Worker &const_method_called_with);
800*6777b538SAndroid Build Coastguard Worker
801*6777b538SAndroid Build Coastguard Worker {
802*6777b538SAndroid Build Coastguard Worker RunLoop loop;
803*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgVoidReturn::set_loop).WithArgs(&loop);
804*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgVoidReturn::Method).WithArgs(123);
805*6777b538SAndroid Build Coastguard Worker loop.Run();
806*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(123, method_called_with);
807*6777b538SAndroid Build Coastguard Worker }
808*6777b538SAndroid Build Coastguard Worker
809*6777b538SAndroid Build Coastguard Worker {
810*6777b538SAndroid Build Coastguard Worker RunLoop loop;
811*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgVoidReturn::set_loop).WithArgs(&loop);
812*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgVoidReturn::ConstMethod).WithArgs(456);
813*6777b538SAndroid Build Coastguard Worker loop.Run();
814*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(456, const_method_called_with);
815*6777b538SAndroid Build Coastguard Worker }
816*6777b538SAndroid Build Coastguard Worker }
817*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallNoArgsVoidThen)818*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallNoArgsVoidThen) {
819*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<NoArgsVoidReturn> s(this->background_task_runner_);
820*6777b538SAndroid Build Coastguard Worker
821*6777b538SAndroid Build Coastguard Worker {
822*6777b538SAndroid Build Coastguard Worker RunLoop loop;
823*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::Method).Then(BindLambdaForTesting([&]() {
824*6777b538SAndroid Build Coastguard Worker loop.Quit();
825*6777b538SAndroid Build Coastguard Worker }));
826*6777b538SAndroid Build Coastguard Worker loop.Run();
827*6777b538SAndroid Build Coastguard Worker }
828*6777b538SAndroid Build Coastguard Worker
829*6777b538SAndroid Build Coastguard Worker {
830*6777b538SAndroid Build Coastguard Worker RunLoop loop;
831*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::ConstMethod)
832*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&]() { loop.Quit(); }));
833*6777b538SAndroid Build Coastguard Worker loop.Run();
834*6777b538SAndroid Build Coastguard Worker }
835*6777b538SAndroid Build Coastguard Worker }
836*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallNoArgsIntThen)837*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallNoArgsIntThen) {
838*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<NoArgsIntReturn> s(this->background_task_runner_);
839*6777b538SAndroid Build Coastguard Worker
840*6777b538SAndroid Build Coastguard Worker {
841*6777b538SAndroid Build Coastguard Worker RunLoop loop;
842*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsIntReturn::Method)
843*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&](int result) {
844*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(123, result);
845*6777b538SAndroid Build Coastguard Worker loop.Quit();
846*6777b538SAndroid Build Coastguard Worker }));
847*6777b538SAndroid Build Coastguard Worker loop.Run();
848*6777b538SAndroid Build Coastguard Worker }
849*6777b538SAndroid Build Coastguard Worker
850*6777b538SAndroid Build Coastguard Worker {
851*6777b538SAndroid Build Coastguard Worker RunLoop loop;
852*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsIntReturn::ConstMethod)
853*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&](int result) {
854*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(456, result);
855*6777b538SAndroid Build Coastguard Worker loop.Quit();
856*6777b538SAndroid Build Coastguard Worker }));
857*6777b538SAndroid Build Coastguard Worker loop.Run();
858*6777b538SAndroid Build Coastguard Worker }
859*6777b538SAndroid Build Coastguard Worker }
860*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallWithArgsVoidThen)861*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallWithArgsVoidThen) {
862*6777b538SAndroid Build Coastguard Worker int method_called_with = 0;
863*6777b538SAndroid Build Coastguard Worker int const_method_called_with = 0;
864*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IntArgVoidReturn> s(this->background_task_runner_,
865*6777b538SAndroid Build Coastguard Worker &method_called_with,
866*6777b538SAndroid Build Coastguard Worker &const_method_called_with);
867*6777b538SAndroid Build Coastguard Worker
868*6777b538SAndroid Build Coastguard Worker {
869*6777b538SAndroid Build Coastguard Worker RunLoop loop;
870*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgVoidReturn::Method)
871*6777b538SAndroid Build Coastguard Worker .WithArgs(123)
872*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&] { loop.Quit(); }));
873*6777b538SAndroid Build Coastguard Worker loop.Run();
874*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(123, method_called_with);
875*6777b538SAndroid Build Coastguard Worker }
876*6777b538SAndroid Build Coastguard Worker
877*6777b538SAndroid Build Coastguard Worker {
878*6777b538SAndroid Build Coastguard Worker RunLoop loop;
879*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgVoidReturn::ConstMethod)
880*6777b538SAndroid Build Coastguard Worker .WithArgs(456)
881*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&] { loop.Quit(); }));
882*6777b538SAndroid Build Coastguard Worker loop.Run();
883*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(456, const_method_called_with);
884*6777b538SAndroid Build Coastguard Worker }
885*6777b538SAndroid Build Coastguard Worker }
886*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallWithArgsIntThen)887*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallWithArgsIntThen) {
888*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IntArgIntReturn> s(this->background_task_runner_);
889*6777b538SAndroid Build Coastguard Worker
890*6777b538SAndroid Build Coastguard Worker {
891*6777b538SAndroid Build Coastguard Worker RunLoop loop;
892*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgIntReturn::Method)
893*6777b538SAndroid Build Coastguard Worker .WithArgs(123)
894*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&](int result) {
895*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-123, result);
896*6777b538SAndroid Build Coastguard Worker loop.Quit();
897*6777b538SAndroid Build Coastguard Worker }));
898*6777b538SAndroid Build Coastguard Worker loop.Run();
899*6777b538SAndroid Build Coastguard Worker }
900*6777b538SAndroid Build Coastguard Worker
901*6777b538SAndroid Build Coastguard Worker {
902*6777b538SAndroid Build Coastguard Worker RunLoop loop;
903*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&IntArgIntReturn::ConstMethod)
904*6777b538SAndroid Build Coastguard Worker .WithArgs(456)
905*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&](int result) {
906*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-456, result);
907*6777b538SAndroid Build Coastguard Worker loop.Quit();
908*6777b538SAndroid Build Coastguard Worker }));
909*6777b538SAndroid Build Coastguard Worker loop.Run();
910*6777b538SAndroid Build Coastguard Worker }
911*6777b538SAndroid Build Coastguard Worker }
912*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallIsConstQualified)913*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallIsConstQualified) {
914*6777b538SAndroid Build Coastguard Worker // Tests that both const and non-const methods may be called through a
915*6777b538SAndroid Build Coastguard Worker // const-qualified SequenceBound.
916*6777b538SAndroid Build Coastguard Worker const SEQUENCE_BOUND_T<NoArgsVoidReturn> s(this->background_task_runner_);
917*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::ConstMethod);
918*6777b538SAndroid Build Coastguard Worker s.AsyncCall(&NoArgsVoidReturn::Method);
919*6777b538SAndroid Build Coastguard Worker }
920*6777b538SAndroid Build Coastguard Worker
921*6777b538SAndroid Build Coastguard Worker class IgnoreResultTestHelperWithNoArgs {
922*6777b538SAndroid Build Coastguard Worker public:
IgnoreResultTestHelperWithNoArgs(RunLoop * loop,bool * called)923*6777b538SAndroid Build Coastguard Worker explicit IgnoreResultTestHelperWithNoArgs(RunLoop* loop, bool* called)
924*6777b538SAndroid Build Coastguard Worker : loop_(loop), called_(called) {}
925*6777b538SAndroid Build Coastguard Worker
ConstMethod() const926*6777b538SAndroid Build Coastguard Worker int ConstMethod() const {
927*6777b538SAndroid Build Coastguard Worker if (loop_) {
928*6777b538SAndroid Build Coastguard Worker loop_->Quit();
929*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
930*6777b538SAndroid Build Coastguard Worker }
931*6777b538SAndroid Build Coastguard Worker if (called_) {
932*6777b538SAndroid Build Coastguard Worker *called_ = true;
933*6777b538SAndroid Build Coastguard Worker called_ = nullptr;
934*6777b538SAndroid Build Coastguard Worker }
935*6777b538SAndroid Build Coastguard Worker return 0;
936*6777b538SAndroid Build Coastguard Worker }
937*6777b538SAndroid Build Coastguard Worker
Method()938*6777b538SAndroid Build Coastguard Worker int Method() {
939*6777b538SAndroid Build Coastguard Worker if (loop_) {
940*6777b538SAndroid Build Coastguard Worker loop_->Quit();
941*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
942*6777b538SAndroid Build Coastguard Worker }
943*6777b538SAndroid Build Coastguard Worker if (called_) {
944*6777b538SAndroid Build Coastguard Worker *called_ = true;
945*6777b538SAndroid Build Coastguard Worker called_ = nullptr;
946*6777b538SAndroid Build Coastguard Worker }
947*6777b538SAndroid Build Coastguard Worker return 0;
948*6777b538SAndroid Build Coastguard Worker }
949*6777b538SAndroid Build Coastguard Worker
950*6777b538SAndroid Build Coastguard Worker private:
951*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<RunLoop> loop_ = nullptr;
952*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<bool> called_ = nullptr;
953*6777b538SAndroid Build Coastguard Worker };
954*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallIgnoreResultNoArgs)955*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallIgnoreResultNoArgs) {
956*6777b538SAndroid Build Coastguard Worker {
957*6777b538SAndroid Build Coastguard Worker RunLoop loop;
958*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithNoArgs> s(
959*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, &loop, nullptr);
960*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithNoArgs::ConstMethod));
961*6777b538SAndroid Build Coastguard Worker loop.Run();
962*6777b538SAndroid Build Coastguard Worker }
963*6777b538SAndroid Build Coastguard Worker
964*6777b538SAndroid Build Coastguard Worker {
965*6777b538SAndroid Build Coastguard Worker RunLoop loop;
966*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithNoArgs> s(
967*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, &loop, nullptr);
968*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithNoArgs::Method));
969*6777b538SAndroid Build Coastguard Worker loop.Run();
970*6777b538SAndroid Build Coastguard Worker }
971*6777b538SAndroid Build Coastguard Worker }
972*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallIgnoreResultThen)973*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallIgnoreResultThen) {
974*6777b538SAndroid Build Coastguard Worker {
975*6777b538SAndroid Build Coastguard Worker RunLoop loop;
976*6777b538SAndroid Build Coastguard Worker bool called = false;
977*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithNoArgs> s(
978*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, nullptr, &called);
979*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithNoArgs::ConstMethod))
980*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&] { loop.Quit(); }));
981*6777b538SAndroid Build Coastguard Worker loop.Run();
982*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(called);
983*6777b538SAndroid Build Coastguard Worker }
984*6777b538SAndroid Build Coastguard Worker
985*6777b538SAndroid Build Coastguard Worker {
986*6777b538SAndroid Build Coastguard Worker RunLoop loop;
987*6777b538SAndroid Build Coastguard Worker bool called = false;
988*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithNoArgs> s(
989*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, nullptr, &called);
990*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithNoArgs::Method))
991*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&] { loop.Quit(); }));
992*6777b538SAndroid Build Coastguard Worker loop.Run();
993*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(called);
994*6777b538SAndroid Build Coastguard Worker }
995*6777b538SAndroid Build Coastguard Worker }
996*6777b538SAndroid Build Coastguard Worker
997*6777b538SAndroid Build Coastguard Worker class IgnoreResultTestHelperWithArgs {
998*6777b538SAndroid Build Coastguard Worker public:
IgnoreResultTestHelperWithArgs(RunLoop * loop,int & value)999*6777b538SAndroid Build Coastguard Worker IgnoreResultTestHelperWithArgs(RunLoop* loop, int& value)
1000*6777b538SAndroid Build Coastguard Worker : loop_(loop), value_(&value) {}
1001*6777b538SAndroid Build Coastguard Worker
ConstMethod(int arg) const1002*6777b538SAndroid Build Coastguard Worker int ConstMethod(int arg) const {
1003*6777b538SAndroid Build Coastguard Worker if (value_) {
1004*6777b538SAndroid Build Coastguard Worker *value_ = arg;
1005*6777b538SAndroid Build Coastguard Worker value_ = nullptr;
1006*6777b538SAndroid Build Coastguard Worker }
1007*6777b538SAndroid Build Coastguard Worker if (loop_) {
1008*6777b538SAndroid Build Coastguard Worker loop_->Quit();
1009*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
1010*6777b538SAndroid Build Coastguard Worker }
1011*6777b538SAndroid Build Coastguard Worker return arg;
1012*6777b538SAndroid Build Coastguard Worker }
1013*6777b538SAndroid Build Coastguard Worker
Method(int arg)1014*6777b538SAndroid Build Coastguard Worker int Method(int arg) {
1015*6777b538SAndroid Build Coastguard Worker if (value_) {
1016*6777b538SAndroid Build Coastguard Worker *value_ = arg;
1017*6777b538SAndroid Build Coastguard Worker value_ = nullptr;
1018*6777b538SAndroid Build Coastguard Worker }
1019*6777b538SAndroid Build Coastguard Worker if (loop_) {
1020*6777b538SAndroid Build Coastguard Worker loop_->Quit();
1021*6777b538SAndroid Build Coastguard Worker loop_ = nullptr;
1022*6777b538SAndroid Build Coastguard Worker }
1023*6777b538SAndroid Build Coastguard Worker return arg;
1024*6777b538SAndroid Build Coastguard Worker }
1025*6777b538SAndroid Build Coastguard Worker
1026*6777b538SAndroid Build Coastguard Worker private:
1027*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<RunLoop> loop_ = nullptr;
1028*6777b538SAndroid Build Coastguard Worker mutable raw_ptr<int> value_;
1029*6777b538SAndroid Build Coastguard Worker };
1030*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallIgnoreResultWithArgs)1031*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallIgnoreResultWithArgs) {
1032*6777b538SAndroid Build Coastguard Worker {
1033*6777b538SAndroid Build Coastguard Worker RunLoop loop;
1034*6777b538SAndroid Build Coastguard Worker int result = 0;
1035*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithArgs> s(
1036*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, &loop, std::ref(result));
1037*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithArgs::ConstMethod))
1038*6777b538SAndroid Build Coastguard Worker .WithArgs(60);
1039*6777b538SAndroid Build Coastguard Worker loop.Run();
1040*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(60, result);
1041*6777b538SAndroid Build Coastguard Worker }
1042*6777b538SAndroid Build Coastguard Worker
1043*6777b538SAndroid Build Coastguard Worker {
1044*6777b538SAndroid Build Coastguard Worker RunLoop loop;
1045*6777b538SAndroid Build Coastguard Worker int result = 0;
1046*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithArgs> s(
1047*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, &loop, std::ref(result));
1048*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithArgs::Method))
1049*6777b538SAndroid Build Coastguard Worker .WithArgs(06);
1050*6777b538SAndroid Build Coastguard Worker loop.Run();
1051*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(06, result);
1052*6777b538SAndroid Build Coastguard Worker }
1053*6777b538SAndroid Build Coastguard Worker }
1054*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(SequenceBoundTest,AsyncCallIgnoreResultWithArgsThen)1055*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, AsyncCallIgnoreResultWithArgsThen) {
1056*6777b538SAndroid Build Coastguard Worker {
1057*6777b538SAndroid Build Coastguard Worker RunLoop loop;
1058*6777b538SAndroid Build Coastguard Worker int result = 0;
1059*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithArgs> s(
1060*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, nullptr, std::ref(result));
1061*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithArgs::ConstMethod))
1062*6777b538SAndroid Build Coastguard Worker .WithArgs(60)
1063*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&] { loop.Quit(); }));
1064*6777b538SAndroid Build Coastguard Worker loop.Run();
1065*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(60, result);
1066*6777b538SAndroid Build Coastguard Worker }
1067*6777b538SAndroid Build Coastguard Worker
1068*6777b538SAndroid Build Coastguard Worker {
1069*6777b538SAndroid Build Coastguard Worker RunLoop loop;
1070*6777b538SAndroid Build Coastguard Worker int result = 0;
1071*6777b538SAndroid Build Coastguard Worker SEQUENCE_BOUND_T<IgnoreResultTestHelperWithArgs> s(
1072*6777b538SAndroid Build Coastguard Worker this->background_task_runner_, nullptr, std::ref(result));
1073*6777b538SAndroid Build Coastguard Worker s.AsyncCall(IgnoreResult(&IgnoreResultTestHelperWithArgs::Method))
1074*6777b538SAndroid Build Coastguard Worker .WithArgs(06)
1075*6777b538SAndroid Build Coastguard Worker .Then(BindLambdaForTesting([&] { loop.Quit(); }));
1076*6777b538SAndroid Build Coastguard Worker loop.Run();
1077*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(06, result);
1078*6777b538SAndroid Build Coastguard Worker }
1079*6777b538SAndroid Build Coastguard Worker }
1080*6777b538SAndroid Build Coastguard Worker
1081*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1382549): Maybe use the nocompile harness here instead
1082*6777b538SAndroid Build Coastguard Worker // of being "clever"...
TYPED_TEST(SequenceBoundTest,NoCompileTests)1083*6777b538SAndroid Build Coastguard Worker TYPED_TEST(SequenceBoundTest, NoCompileTests) {
1084*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1382549): Test calling WithArgs() on a method that
1085*6777b538SAndroid Build Coastguard Worker // takes no arguments.
1086*6777b538SAndroid Build Coastguard Worker //
1087*6777b538SAndroid Build Coastguard Worker // Given:
1088*6777b538SAndroid Build Coastguard Worker // class C {
1089*6777b538SAndroid Build Coastguard Worker // void F();
1090*6777b538SAndroid Build Coastguard Worker // };
1091*6777b538SAndroid Build Coastguard Worker //
1092*6777b538SAndroid Build Coastguard Worker // Then:
1093*6777b538SAndroid Build Coastguard Worker // SequenceBound<C> s(...);
1094*6777b538SAndroid Build Coastguard Worker // s.AsyncCall(&C::F).WithArgs(...);
1095*6777b538SAndroid Build Coastguard Worker //
1096*6777b538SAndroid Build Coastguard Worker // should not compile.
1097*6777b538SAndroid Build Coastguard Worker //
1098*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1382549): Test calling Then() before calling
1099*6777b538SAndroid Build Coastguard Worker // WithArgs().
1100*6777b538SAndroid Build Coastguard Worker //
1101*6777b538SAndroid Build Coastguard Worker // Given:
1102*6777b538SAndroid Build Coastguard Worker // class C {
1103*6777b538SAndroid Build Coastguard Worker // void F(int);
1104*6777b538SAndroid Build Coastguard Worker // };
1105*6777b538SAndroid Build Coastguard Worker //
1106*6777b538SAndroid Build Coastguard Worker // Then:
1107*6777b538SAndroid Build Coastguard Worker // SequenceBound<C> s(...);
1108*6777b538SAndroid Build Coastguard Worker // s.AsyncCall(&C::F).Then(...).WithArgs(...);
1109*6777b538SAndroid Build Coastguard Worker //
1110*6777b538SAndroid Build Coastguard Worker // should not compile.
1111*6777b538SAndroid Build Coastguard Worker //
1112*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1382549): Add no-compile tests for converting
1113*6777b538SAndroid Build Coastguard Worker // between SequenceBound<T> and SequenceBound<std::unique_ptr<T>>.
1114*6777b538SAndroid Build Coastguard Worker }
1115*6777b538SAndroid Build Coastguard Worker #undef SequenceBound
1116*6777b538SAndroid Build Coastguard Worker
1117*6777b538SAndroid Build Coastguard Worker class SequenceBoundDeathTest : public ::testing::Test {
1118*6777b538SAndroid Build Coastguard Worker protected:
TearDown()1119*6777b538SAndroid Build Coastguard Worker void TearDown() override {
1120*6777b538SAndroid Build Coastguard Worker // Make sure that any objects owned by `SequenceBound` have been destroyed
1121*6777b538SAndroid Build Coastguard Worker // to avoid tripping leak detection.
1122*6777b538SAndroid Build Coastguard Worker RunLoop run_loop;
1123*6777b538SAndroid Build Coastguard Worker task_runner_->PostTask(FROM_HERE, run_loop.QuitClosure());
1124*6777b538SAndroid Build Coastguard Worker run_loop.Run();
1125*6777b538SAndroid Build Coastguard Worker }
1126*6777b538SAndroid Build Coastguard Worker
1127*6777b538SAndroid Build Coastguard Worker // Death tests use fork(), which can interact (very) poorly with threads.
1128*6777b538SAndroid Build Coastguard Worker test::SingleThreadTaskEnvironment task_environment_;
1129*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner_ =
1130*6777b538SAndroid Build Coastguard Worker SequencedTaskRunner::GetCurrentDefault();
1131*6777b538SAndroid Build Coastguard Worker };
1132*6777b538SAndroid Build Coastguard Worker
TEST_F(SequenceBoundDeathTest,AsyncCallIntArgNoWithArgsShouldCheck)1133*6777b538SAndroid Build Coastguard Worker TEST_F(SequenceBoundDeathTest, AsyncCallIntArgNoWithArgsShouldCheck) {
1134*6777b538SAndroid Build Coastguard Worker SequenceBound<IntArgIntReturn> s(task_runner_);
1135*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH_IF_SUPPORTED(s.AsyncCall(&IntArgIntReturn::Method), "");
1136*6777b538SAndroid Build Coastguard Worker }
1137*6777b538SAndroid Build Coastguard Worker
TEST_F(SequenceBoundDeathTest,AsyncCallIntReturnNoThenShouldCheck)1138*6777b538SAndroid Build Coastguard Worker TEST_F(SequenceBoundDeathTest, AsyncCallIntReturnNoThenShouldCheck) {
1139*6777b538SAndroid Build Coastguard Worker {
1140*6777b538SAndroid Build Coastguard Worker SequenceBound<NoArgsIntReturn> s(task_runner_);
1141*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH_IF_SUPPORTED(s.AsyncCall(&NoArgsIntReturn::Method), "");
1142*6777b538SAndroid Build Coastguard Worker }
1143*6777b538SAndroid Build Coastguard Worker
1144*6777b538SAndroid Build Coastguard Worker {
1145*6777b538SAndroid Build Coastguard Worker SequenceBound<IntArgIntReturn> s(task_runner_);
1146*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH_IF_SUPPORTED(s.AsyncCall(&IntArgIntReturn::Method).WithArgs(0),
1147*6777b538SAndroid Build Coastguard Worker "");
1148*6777b538SAndroid Build Coastguard Worker }
1149*6777b538SAndroid Build Coastguard Worker }
1150*6777b538SAndroid Build Coastguard Worker
1151*6777b538SAndroid Build Coastguard Worker } // namespace
1152*6777b538SAndroid Build Coastguard Worker
1153*6777b538SAndroid Build Coastguard Worker } // namespace base
1154