15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/bindings/error_handler.h"
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/environment/environment.h"
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/utility/run_loop.h"
8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h"
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace mojo {
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace test {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ErrorObserver : public ErrorHandler {
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ErrorObserver() : encountered_error_(false) {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool encountered_error() const { return encountered_error_; }
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  virtual void OnConnectionError() MOJO_OVERRIDE {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    encountered_error_ = true;
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool encountered_error_;
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class MathCalculatorImpl : public InterfaceImpl<math::Calculator> {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~MathCalculatorImpl() {}
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MathCalculatorImpl()
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : total_(0.0),
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        got_connection_(false) {
380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnConnectionEstablished() MOJO_OVERRIDE {
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    got_connection_ = true;
420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Clear() MOJO_OVERRIDE {
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client()->Output(total_);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Add(double value) MOJO_OVERRIDE {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    total_ += value;
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client()->Output(total_);
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Multiply(double value) MOJO_OVERRIDE {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    total_ *= value;
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client()->Output(total_);
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool got_connection() const {
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return got_connection_;
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  double total_;
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool got_connection_;
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MathCalculatorUIImpl : public math::CalculatorUI {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  explicit MathCalculatorUIImpl(math::CalculatorPtr calculator)
700de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)      : calculator_(calculator.Pass()),
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        output_(0.0) {
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    calculator_.set_client(this);
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool WaitForIncomingMethodCall() {
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return calculator_.WaitForIncomingMethodCall();
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool encountered_error() const {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return calculator_.encountered_error();
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Add(double value) {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    calculator_->Add(value);
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Subtract(double value) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    calculator_->Add(-value);
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Multiply(double value) {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    calculator_->Multiply(value);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Divide(double value) {
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    calculator_->Multiply(1.0 / value);
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  double GetOutput() const {
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return output_;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // math::CalculatorUI implementation:
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Output(double value) MOJO_OVERRIDE {
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    output_ = value;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1090de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr calculator_;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  double output_;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class SelfDestructingMathCalculatorUIImpl : public math::CalculatorUI {
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit SelfDestructingMathCalculatorUIImpl(math::CalculatorPtr calculator)
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : calculator_(calculator.Pass()),
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        nesting_level_(0) {
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ++num_instances_;
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    calculator_.set_client(this);
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void BeginTest(bool nested) {
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    nesting_level_ = nested ? 2 : 1;
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    calculator_->Add(1.0);
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static int num_instances() { return num_instances_; }
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~SelfDestructingMathCalculatorUIImpl() {
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    --num_instances_;
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void Output(double value) MOJO_OVERRIDE {
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (--nesting_level_ > 0) {
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Add some more and wait for re-entrant call to Output!
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      calculator_->Add(1.0);
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      RunLoop::current()->RunUntilIdle();
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      delete this;
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  math::CalculatorPtr calculator_;
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int nesting_level_;
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static int num_instances_;
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int SelfDestructingMathCalculatorUIImpl::num_instances_ = 0;
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ReentrantServiceImpl : public InterfaceImpl<sample::Service> {
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~ReentrantServiceImpl() {}
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ReentrantServiceImpl()
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : got_connection_(false), call_depth_(0), max_call_depth_(0) {}
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnConnectionEstablished() MOJO_OVERRIDE {
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    got_connection_ = true;
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool got_connection() const {
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return got_connection_;
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int max_call_depth() { return max_call_depth_; }
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Frobinate(sample::FooPtr foo,
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         sample::Service::BazOptions baz,
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         sample::PortPtr port) MOJO_OVERRIDE {
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    max_call_depth_ = std::max(++call_depth_, max_call_depth_);
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (call_depth_ == 1) {
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      EXPECT_TRUE(WaitForIncomingMethodCall());
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    call_depth_--;
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void GetPort(mojo::InterfaceRequest<sample::Port> port)
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MOJO_OVERRIDE {}
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool got_connection_;
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int call_depth_;
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int max_call_depth_;
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class InterfacePtrTest : public testing::Test {
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  virtual ~InterfacePtrTest() {
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    loop_.RunUntilIdle();
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  void PumpMessages() {
1950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    loop_.RunUntilIdle();
1960de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Environment env_;
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop loop_;
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2030de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(InterfacePtrTest, EndToEnd) {
2040de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr calc;
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc);
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(impl->got_connection());
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Suppose this is instantiated in a process that has pipe1_.
2090de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MathCalculatorUIImpl calculator_ui(calc.Pass());
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  calculator_ui.Add(2.0);
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  calculator_ui.Multiply(5.0);
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpMessages();
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(10.0, calculator_ui.GetOutput());
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
219116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(InterfacePtrTest, EndToEnd_Synchronous) {
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  math::CalculatorPtr calc;
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc);
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(impl->got_connection());
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Suppose this is instantiated in a process that has pipe1_.
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MathCalculatorUIImpl calculator_ui(calc.Pass());
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(0.0, calculator_ui.GetOutput());
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  calculator_ui.Add(2.0);
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(0.0, calculator_ui.GetOutput());
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  impl->WaitForIncomingMethodCall();
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  calculator_ui.WaitForIncomingMethodCall();
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(2.0, calculator_ui.GetOutput());
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  calculator_ui.Multiply(5.0);
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(2.0, calculator_ui.GetOutput());
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  impl->WaitForIncomingMethodCall();
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  calculator_ui.WaitForIncomingMethodCall();
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(10.0, calculator_ui.GetOutput());
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(InterfacePtrTest, Movable) {
2430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr a;
2440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr b;
2450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  BindToProxy(new MathCalculatorImpl(), &b);
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(!a);
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(!b);
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  a = b.Pass();
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(!a);
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(!b);
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(InterfacePtrTest, Resettable) {
2570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr a;
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(!a);
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MessagePipe pipe;
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Save this so we can test it later.
2640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  Handle handle = pipe.handle0.get();
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2660de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  a = MakeProxy<math::Calculator>(pipe.handle0.Pass());
2670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(!a);
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  a.reset();
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(!a);
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(a.internal_state()->router_for_testing());
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test that handle was closed.
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, CloseRaw(handle));
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(InterfacePtrTest, EncounteredError) {
2800de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr proxy;
2810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy);
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MathCalculatorUIImpl calculator_ui(proxy.Pass());
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  calculator_ui.Add(2.0);
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpMessages();
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2.0, calculator_ui.GetOutput());
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(calculator_ui.encountered_error());
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  calculator_ui.Multiply(5.0);
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(calculator_ui.encountered_error());
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Close the server.
2940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  server->internal_state()->router()->CloseMessagePipe();
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The state change isn't picked up locally yet.
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(calculator_ui.encountered_error());
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpMessages();
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OK, now we see the error.
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(calculator_ui.encountered_error());
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3050de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(InterfacePtrTest, EncounteredErrorCallback) {
3060de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  math::CalculatorPtr proxy;
3070de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MathCalculatorImpl* server = BindToProxy(new MathCalculatorImpl(), &proxy);
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ErrorObserver error_observer;
3100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  proxy.set_error_handler(&error_observer);
3110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
3120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MathCalculatorUIImpl calculator_ui(proxy.Pass());
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  calculator_ui.Add(2.0);
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpMessages();
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2.0, calculator_ui.GetOutput());
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(calculator_ui.encountered_error());
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  calculator_ui.Multiply(5.0);
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(calculator_ui.encountered_error());
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Close the server.
3230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  server->internal_state()->router()->CloseMessagePipe();
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The state change isn't picked up locally yet.
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(calculator_ui.encountered_error());
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PumpMessages();
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OK, now we see the error.
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(calculator_ui.encountered_error());
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should have also been able to observe the error through the
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ErrorHandler interface.
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(error_observer.encountered_error());
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(InterfacePtrTest, NoClientAttribute) {
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This is a test to ensure the following compiles. The sample::Port interface
3400de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // does not have an explicit Client attribute.
3410de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  sample::PortPtr port;
3420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MessagePipe pipe;
3430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  port.Bind(pipe.handle0.Pass());
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(InterfacePtrTest, DestroyInterfacePtrOnClientMethod) {
347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  math::CalculatorPtr proxy;
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  BindToProxy(new MathCalculatorImpl(), &proxy);
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances());
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SelfDestructingMathCalculatorUIImpl* impl =
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new SelfDestructingMathCalculatorUIImpl(proxy.Pass());
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  impl->BeginTest(false);
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PumpMessages();
357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances());
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnClientMethod) {
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  math::CalculatorPtr proxy;
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  BindToProxy(new MathCalculatorImpl(), &proxy);
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances());
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SelfDestructingMathCalculatorUIImpl* impl =
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new SelfDestructingMathCalculatorUIImpl(proxy.Pass());
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  impl->BeginTest(true);
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PumpMessages();
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0, SelfDestructingMathCalculatorUIImpl::num_instances());
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
376116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) {
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sample::ServicePtr proxy;
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ReentrantServiceImpl* impl = BindToProxy(new ReentrantServiceImpl(), &proxy);
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(impl->got_connection());
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  proxy->Frobinate(sample::FooPtr(),
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   sample::Service::BAZ_OPTIONS_REGULAR,
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   sample::PortPtr());
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  proxy->Frobinate(sample::FooPtr(),
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   sample::Service::BAZ_OPTIONS_REGULAR,
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   sample::PortPtr());
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PumpMessages();
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(2, impl->max_call_depth());
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace test
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace mojo
396