Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1121)

Side by Side Diff: mojo/public/cpp/bindings/tests/synchronous_interface_ptr_unittest.cc

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/public/cpp/bindings/synchronous_interface_ptr.h"
6
7 #include <thread>
8 #include <utility>
9
10 #include "gtest/gtest.h"
11 #include "mojo/public/cpp/bindings/binding.h"
12 #include "mojo/public/cpp/bindings/interface_request.h"
13 #include "mojo/public/cpp/bindings/strong_binding.h"
14 #include "mojo/public/cpp/utility/run_loop.h"
15 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom-sync.h"
16 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h"
17 #include "mojo/public/interfaces/bindings/tests/scoping.mojom-sync.h"
18 #include "mojo/public/interfaces/bindings/tests/scoping.mojom.h"
19
20 namespace mojo {
21 namespace test {
22 namespace {
23
24 using CalcCallback = mojo::Callback<void(double)>;
25
26 // This runs in a separate thread.
27 class MathCalculatorImpl : public math::Calculator {
28 public:
29 explicit MathCalculatorImpl(InterfaceRequest<math::Calculator> request)
30 : total_(0.0), binding_(this, request.Pass()) {}
31 ~MathCalculatorImpl() override {}
32
33 void Clear(const CalcCallback& callback) override {
34 total_ = 0.0;
35 callback.Run(total_);
36 }
37
38 void Add(double value, const CalcCallback& callback) override {
39 total_ += value;
40 callback.Run(total_);
41 }
42
43 void Multiply(double value, const CalcCallback& callback) override {
44 total_ *= value;
45 callback.Run(total_);
46 }
47
48 private:
49 double total_;
50 Binding<math::Calculator> binding_;
51 };
52
53 class SynchronousInterfacePtrTest : public testing::Test {
54 public:
55 ~SynchronousInterfacePtrTest() override { loop_.RunUntilIdle(); }
56
57 void PumpMessages() { loop_.RunUntilIdle(); }
58
59 // This is meant to be passed in to an std::thread -- the thread will have its
60 // own RunLoop!
61 static void StartMathCalculator(InterfaceRequest<math::Calculator> server) {
62 // Runloop is thread-local, and this is what the MathCalculatorImpl will end
63 // up using.
64 RunLoop loop;
65 MathCalculatorImpl calc_impl(std::move(server));
66 loop.Run();
67 }
68
69 private:
70 RunLoop loop_;
71 };
72
73 TEST_F(SynchronousInterfacePtrTest, IsBound) {
74 SynchronousInterfacePtr<math::Calculator> calc;
75 EXPECT_FALSE(calc.is_bound());
76 EXPECT_FALSE(calc);
77
78 MathCalculatorImpl calc_impl(GetSynchronousProxy(&calc));
79 EXPECT_TRUE(calc.is_bound());
80 EXPECT_TRUE(calc);
81 }
82
83 // Do an end to end
84 TEST_F(SynchronousInterfacePtrTest, EndToEnd) {
85 SynchronousInterfacePtr<math::Calculator> calc;
86 std::thread server(StartMathCalculator, GetSynchronousProxy(&calc));
87
88 double out;
89 calc->Add(2.0, &out);
90 calc->Multiply(5.0, &out);
91 EXPECT_EQ(10.0, out);
92
93 calc.PassInterfaceHandle();
94 server.join();
95 }
96
97 // Move them around.
98 TEST_F(SynchronousInterfacePtrTest, Movable) {
99 SynchronousInterfacePtr<math::Calculator> a;
100 SynchronousInterfacePtr<math::Calculator> b;
101 MathCalculatorImpl calc_impl(GetSynchronousProxy(&b));
102
103 EXPECT_TRUE(!a);
104 EXPECT_FALSE(!b);
105
106 a = std::move(b);
107
108 EXPECT_FALSE(!a);
109 EXPECT_TRUE(!b);
110 }
111
112 // Test ::reset() and the explicit bool operator.
113 TEST_F(SynchronousInterfacePtrTest, Resettable) {
114 MessagePipe pipe;
115 // Save this so we can test it later.
116 Handle handle = pipe.handle0.get();
117
118 SynchronousInterfacePtr<math::Calculator> a;
119 EXPECT_TRUE(!a);
120 a = SynchronousInterfacePtr<math::Calculator>::Create(
121 InterfaceHandle<math::Calculator>(std::move(pipe.handle0), 0u));
122 EXPECT_FALSE(!a);
123
124 a.reset();
125 EXPECT_TRUE(!a);
126
127 // Test that handle was closed.
128 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle));
129 }
130
131 TEST_F(SynchronousInterfacePtrTest, SetNull) {
132 MessagePipe pipe;
133 auto a = SynchronousInterfacePtr<math::Calculator>::Create(
134 InterfaceHandle<math::Calculator>(std::move(pipe.handle0), 0u));
135
136 EXPECT_TRUE(a);
137 a = nullptr;
138 EXPECT_FALSE(a);
139 }
140
141 // SynchronousInterfacePtr<> will return false on method invocations if its
142 // underlying end of the pipe is dead.
143 TEST_F(SynchronousInterfacePtrTest, EncounteredError) {
144 SynchronousInterfacePtr<math::Calculator> calc;
145 {
146 MathCalculatorImpl calc_impl(GetSynchronousProxy(&calc));
147 EXPECT_TRUE(calc.is_bound());
148 }
149
150 EXPECT_TRUE(calc.is_bound());
151
152 double out = 0.0;
153 EXPECT_FALSE(calc->Add(2.0, &out));
154 EXPECT_EQ(0.0, out);
155 }
156
157 class CImpl : public C {
158 public:
159 CImpl(bool* d_called, InterfaceRequest<C> request)
160 : d_called_(d_called), binding_(this, request.Pass()) {}
161 ~CImpl() override {}
162
163 private:
164 void D() override { *d_called_ = true; }
165
166 bool* d_called_;
167 StrongBinding<C> binding_;
168 };
169
170 class BImpl : public B {
171 public:
172 BImpl(bool* d_called, InterfaceRequest<B> request)
173 : d_called_(d_called), binding_(this, request.Pass()) {}
174 ~BImpl() override {}
175
176 private:
177 void GetC(InterfaceRequest<C> c) override { new CImpl(d_called_, c.Pass()); }
178
179 bool* d_called_;
180 StrongBinding<B> binding_;
181 };
182
183 class AImpl : public A {
184 public:
185 explicit AImpl(InterfaceRequest<A> request)
186 : d_called_(false), binding_(this, request.Pass()) {}
187 ~AImpl() override {}
188
189 bool d_called() const { return d_called_; }
190
191 private:
192 void GetB(InterfaceRequest<B> b) override { new BImpl(&d_called_, b.Pass()); }
193
194 bool d_called_;
195 Binding<A> binding_;
196 };
197
198 // Test that, for synchronous method calls that don't have return args, the
199 // bindings return right away, leaving the messages in the message pipe while
200 // closing their end.
201 TEST_F(SynchronousInterfacePtrTest, Scoping) {
202 SynchronousInterfacePtr<A> a;
203 AImpl a_impl(GetSynchronousProxy(&a));
204
205 EXPECT_FALSE(a_impl.d_called());
206
207 {
208 SynchronousInterfacePtr<B> b;
209 a->GetB(GetSynchronousProxy(&b));
210 SynchronousInterfacePtr<C> c;
211 b->GetC(GetSynchronousProxy(&c));
212 c->D();
213 }
214
215 // While B & C have fallen out of scope, the service-side endpoints of the
216 // pipes will remain until they are flushed.
217 EXPECT_FALSE(a_impl.d_called());
218 PumpMessages();
219 EXPECT_TRUE(a_impl.d_called());
220 }
221
222 } // namespace
223 } // namespace test
224 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698