OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/error_handler.h" | 5 #include "mojo/public/cpp/bindings/error_handler.h" |
6 #include "mojo/public/cpp/bindings/remote_ptr.h" | |
7 #include "mojo/public/cpp/environment/environment.h" | 6 #include "mojo/public/cpp/environment/environment.h" |
8 #include "mojo/public/cpp/utility/run_loop.h" | 7 #include "mojo/public/cpp/utility/run_loop.h" |
9 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" | 8 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" |
10 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 9 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
12 | 11 |
13 namespace mojo { | 12 namespace mojo { |
14 namespace test { | 13 namespace test { |
15 namespace { | 14 namespace { |
16 | 15 |
17 class ErrorObserver : public ErrorHandler { | 16 class ErrorObserver : public ErrorHandler { |
18 public: | 17 public: |
19 ErrorObserver() : encountered_error_(false) { | 18 ErrorObserver() : encountered_error_(false) { |
20 } | 19 } |
21 | 20 |
22 bool encountered_error() const { return encountered_error_; } | 21 bool encountered_error() const { return encountered_error_; } |
23 | 22 |
24 virtual void OnError() MOJO_OVERRIDE { | 23 virtual void OnConnectionError() MOJO_OVERRIDE { |
25 encountered_error_ = true; | 24 encountered_error_ = true; |
26 } | 25 } |
27 | 26 |
28 private: | 27 private: |
29 bool encountered_error_; | 28 bool encountered_error_; |
30 }; | 29 }; |
31 | 30 |
32 class MathCalculatorImpl : public math::Calculator { | 31 class MathCalculatorImpl : public InterfaceImpl<math::Calculator> { |
33 public: | 32 public: |
34 virtual ~MathCalculatorImpl() {} | 33 virtual ~MathCalculatorImpl() {} |
35 | 34 |
36 explicit MathCalculatorImpl(math::ScopedCalculatorUIHandle ui_handle) | 35 MathCalculatorImpl() : total_(0.0) { |
37 : ui_(ui_handle.Pass(), this), | 36 } |
38 total_(0.0) { | 37 |
| 38 virtual void OnConnectionError() MOJO_OVERRIDE { |
| 39 delete this; |
| 40 } |
| 41 |
| 42 virtual void SetClient(math::CalculatorUI* ui) MOJO_OVERRIDE { |
| 43 ui_ = ui; |
39 } | 44 } |
40 | 45 |
41 virtual void Clear() MOJO_OVERRIDE { | 46 virtual void Clear() MOJO_OVERRIDE { |
42 ui_->Output(total_); | 47 ui_->Output(total_); |
43 } | 48 } |
44 | 49 |
45 virtual void Add(double value) MOJO_OVERRIDE { | 50 virtual void Add(double value) MOJO_OVERRIDE { |
46 total_ += value; | 51 total_ += value; |
47 ui_->Output(total_); | 52 ui_->Output(total_); |
48 } | 53 } |
49 | 54 |
50 virtual void Multiply(double value) MOJO_OVERRIDE { | 55 virtual void Multiply(double value) MOJO_OVERRIDE { |
51 total_ *= value; | 56 total_ *= value; |
52 ui_->Output(total_); | 57 ui_->Output(total_); |
53 } | 58 } |
54 | 59 |
55 private: | 60 private: |
56 RemotePtr<math::CalculatorUI> ui_; | 61 math::CalculatorUI* ui_; |
57 double total_; | 62 double total_; |
58 }; | 63 }; |
59 | 64 |
60 class MathCalculatorUIImpl : public math::CalculatorUI { | 65 class MathCalculatorUIImpl : public math::CalculatorUI { |
61 public: | 66 public: |
62 explicit MathCalculatorUIImpl(math::ScopedCalculatorHandle calculator_handle, | 67 explicit MathCalculatorUIImpl(math::CalculatorPtr calculator) |
63 ErrorHandler* error_handler = NULL) | 68 : calculator_(calculator.Pass()), |
64 : calculator_(calculator_handle.Pass(), this, error_handler), | |
65 output_(0.0) { | 69 output_(0.0) { |
| 70 calculator_->SetClient(this); |
66 } | 71 } |
67 | 72 |
68 bool encountered_error() const { | 73 bool encountered_error() const { |
69 return calculator_.encountered_error(); | 74 return calculator_.encountered_error(); |
70 } | 75 } |
71 | 76 |
72 void Add(double value) { | 77 void Add(double value) { |
73 calculator_->Add(value); | 78 calculator_->Add(value); |
74 } | 79 } |
75 | 80 |
(...skipping 12 matching lines...) Expand all Loading... |
88 double GetOutput() const { | 93 double GetOutput() const { |
89 return output_; | 94 return output_; |
90 } | 95 } |
91 | 96 |
92 private: | 97 private: |
93 // math::CalculatorUI implementation: | 98 // math::CalculatorUI implementation: |
94 virtual void Output(double value) MOJO_OVERRIDE { | 99 virtual void Output(double value) MOJO_OVERRIDE { |
95 output_ = value; | 100 output_ = value; |
96 } | 101 } |
97 | 102 |
98 RemotePtr<math::Calculator> calculator_; | 103 math::CalculatorPtr calculator_; |
99 double output_; | 104 double output_; |
100 }; | 105 }; |
101 | 106 |
102 class RemotePtrTest : public testing::Test { | 107 class InterfacePtrTest : public testing::Test { |
103 public: | 108 public: |
| 109 virtual ~InterfacePtrTest() { |
| 110 loop_.RunUntilIdle(); |
| 111 } |
| 112 |
104 void PumpMessages() { | 113 void PumpMessages() { |
105 loop_.RunUntilIdle(); | 114 loop_.RunUntilIdle(); |
106 } | 115 } |
107 | 116 |
108 protected: | |
109 InterfacePipe<math::CalculatorUI> pipe_; | |
110 | |
111 private: | 117 private: |
112 Environment env_; | 118 Environment env_; |
113 RunLoop loop_; | 119 RunLoop loop_; |
114 }; | 120 }; |
115 | 121 |
116 TEST_F(RemotePtrTest, EndToEnd) { | 122 TEST_F(InterfacePtrTest, EndToEnd) { |
117 // Suppose this is instantiated in a process that has pipe0_. | 123 math::CalculatorPtr calc; |
118 MathCalculatorImpl calculator(pipe_.handle_to_self.Pass()); | 124 BindToProxy(new MathCalculatorImpl(), &calc); |
119 | 125 |
120 // Suppose this is instantiated in a process that has pipe1_. | 126 // Suppose this is instantiated in a process that has pipe1_. |
121 MathCalculatorUIImpl calculator_ui(pipe_.handle_to_peer.Pass()); | 127 MathCalculatorUIImpl calculator_ui(calc.Pass()); |
122 | 128 |
123 calculator_ui.Add(2.0); | 129 calculator_ui.Add(2.0); |
124 calculator_ui.Multiply(5.0); | 130 calculator_ui.Multiply(5.0); |
125 | 131 |
126 PumpMessages(); | 132 PumpMessages(); |
127 | 133 |
128 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 134 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
129 } | 135 } |
130 | 136 |
131 TEST_F(RemotePtrTest, Movable) { | 137 TEST_F(InterfacePtrTest, Movable) { |
132 RemotePtr<math::Calculator> a; | 138 math::CalculatorPtr a; |
133 RemotePtr<math::Calculator> b(pipe_.handle_to_peer.Pass(), NULL); | 139 math::CalculatorPtr b; |
| 140 BindToProxy(new MathCalculatorImpl(), &b); |
134 | 141 |
135 EXPECT_TRUE(a.is_null()); | 142 EXPECT_TRUE(!a.get()); |
136 EXPECT_FALSE(b.is_null()); | 143 EXPECT_FALSE(!b.get()); |
137 | 144 |
138 a = b.Pass(); | 145 a = b.Pass(); |
139 | 146 |
140 EXPECT_FALSE(a.is_null()); | 147 EXPECT_FALSE(!a.get()); |
141 EXPECT_TRUE(b.is_null()); | 148 EXPECT_TRUE(!b.get()); |
142 } | 149 } |
143 | 150 |
144 TEST_F(RemotePtrTest, Resettable) { | 151 TEST_F(InterfacePtrTest, Resettable) { |
145 RemotePtr<math::Calculator> a; | 152 math::CalculatorPtr a; |
146 | 153 |
147 EXPECT_TRUE(a.is_null()); | 154 EXPECT_TRUE(!a.get()); |
148 | 155 |
149 math::CalculatorHandle handle = pipe_.handle_to_peer.get(); | 156 MessagePipe pipe; |
150 | 157 |
151 a.reset(pipe_.handle_to_peer.Pass(), NULL); | 158 // Save this so we can test it later. |
| 159 Handle handle = pipe.handle0.get(); |
152 | 160 |
153 EXPECT_FALSE(a.is_null()); | 161 a = MakeProxy<math::Calculator>(pipe.handle0.Pass()); |
| 162 |
| 163 EXPECT_FALSE(!a.get()); |
154 | 164 |
155 a.reset(); | 165 a.reset(); |
156 | 166 |
157 EXPECT_TRUE(a.is_null()); | 167 EXPECT_TRUE(!a.get()); |
| 168 EXPECT_FALSE(a.internal_state()->router()); |
158 | 169 |
159 // Test that handle was closed. | 170 // Test that handle was closed. |
160 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); | 171 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle)); |
161 } | 172 } |
162 | 173 |
163 TEST_F(RemotePtrTest, EncounteredError) { | 174 TEST_F(InterfacePtrTest, EncounteredError) { |
164 MathCalculatorImpl* calculator = | 175 math::CalculatorPtr proxy; |
165 new MathCalculatorImpl(pipe_.handle_to_self.Pass()); | 176 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); |
166 | 177 |
167 MathCalculatorUIImpl calculator_ui(pipe_.handle_to_peer.Pass()); | 178 MathCalculatorUIImpl calculator_ui(proxy.Pass()); |
168 | 179 |
169 calculator_ui.Add(2.0); | 180 calculator_ui.Add(2.0); |
170 PumpMessages(); | 181 PumpMessages(); |
171 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 182 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
172 EXPECT_FALSE(calculator_ui.encountered_error()); | 183 EXPECT_FALSE(calculator_ui.encountered_error()); |
173 | 184 |
174 calculator_ui.Multiply(5.0); | 185 calculator_ui.Multiply(5.0); |
175 EXPECT_FALSE(calculator_ui.encountered_error()); | 186 EXPECT_FALSE(calculator_ui.encountered_error()); |
176 | 187 |
177 // Close the other side of the pipe. | 188 // Close the server. |
178 delete calculator; | 189 server->internal_state()->router()->CloseMessagePipe(); |
179 | 190 |
180 // The state change isn't picked up locally yet. | 191 // The state change isn't picked up locally yet. |
181 EXPECT_FALSE(calculator_ui.encountered_error()); | 192 EXPECT_FALSE(calculator_ui.encountered_error()); |
182 | 193 |
183 PumpMessages(); | 194 PumpMessages(); |
184 | 195 |
185 // OK, now we see the error. | 196 // OK, now we see the error. |
186 EXPECT_TRUE(calculator_ui.encountered_error()); | 197 EXPECT_TRUE(calculator_ui.encountered_error()); |
187 } | 198 } |
188 | 199 |
189 TEST_F(RemotePtrTest, EncounteredErrorCallback) { | 200 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { |
190 MathCalculatorImpl* calculator = | 201 math::CalculatorPtr proxy; |
191 new MathCalculatorImpl(pipe_.handle_to_self.Pass()); | 202 MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy); |
192 | 203 |
193 ErrorObserver error_observer; | 204 ErrorObserver error_observer; |
194 MathCalculatorUIImpl calculator_ui(pipe_.handle_to_peer.Pass(), | 205 proxy.set_error_handler(&error_observer); |
195 &error_observer); | 206 |
| 207 MathCalculatorUIImpl calculator_ui(proxy.Pass()); |
196 | 208 |
197 calculator_ui.Add(2.0); | 209 calculator_ui.Add(2.0); |
198 PumpMessages(); | 210 PumpMessages(); |
199 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 211 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
200 EXPECT_FALSE(calculator_ui.encountered_error()); | 212 EXPECT_FALSE(calculator_ui.encountered_error()); |
201 | 213 |
202 calculator_ui.Multiply(5.0); | 214 calculator_ui.Multiply(5.0); |
203 EXPECT_FALSE(calculator_ui.encountered_error()); | 215 EXPECT_FALSE(calculator_ui.encountered_error()); |
204 | 216 |
205 // Close the other side of the pipe. | 217 // Close the server. |
206 delete calculator; | 218 server->internal_state()->router()->CloseMessagePipe(); |
207 | 219 |
208 // The state change isn't picked up locally yet. | 220 // The state change isn't picked up locally yet. |
209 EXPECT_FALSE(calculator_ui.encountered_error()); | 221 EXPECT_FALSE(calculator_ui.encountered_error()); |
210 | 222 |
211 PumpMessages(); | 223 PumpMessages(); |
212 | 224 |
213 // OK, now we see the error. | 225 // OK, now we see the error. |
214 EXPECT_TRUE(calculator_ui.encountered_error()); | 226 EXPECT_TRUE(calculator_ui.encountered_error()); |
215 | 227 |
216 // We should have also been able to observe the error through the | 228 // We should have also been able to observe the error through the |
217 // ErrorHandler interface. | 229 // ErrorHandler interface. |
218 EXPECT_TRUE(error_observer.encountered_error()); | 230 EXPECT_TRUE(error_observer.encountered_error()); |
219 } | 231 } |
220 | 232 |
221 TEST_F(RemotePtrTest, NoPeerAttribute) { | 233 TEST_F(InterfacePtrTest, NoClientAttribute) { |
222 // This is a test to ensure the following compiles. The sample::Port interface | 234 // This is a test to ensure the following compiles. The sample::Port interface |
223 // does not have an explicit Peer attribute. | 235 // does not have an explicit Client attribute. |
224 InterfacePipe<sample::Port, NoInterface> pipe; | 236 sample::PortPtr port; |
225 RemotePtr<sample::Port> port(pipe.handle_to_self.Pass(), NULL); | 237 MessagePipe pipe; |
| 238 port.Bind(pipe.handle0.Pass()); |
226 } | 239 } |
227 | 240 |
228 } // namespace | 241 } // namespace |
229 } // namespace test | 242 } // namespace test |
230 } // namespace mojo | 243 } // namespace mojo |
OLD | NEW |