| 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 |