1// Copyright 2014 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/shell/shell_test_base.h"
6
7#include "base/bind.h"
8#include "base/macros.h"
9#include "base/message_loop/message_loop.h"
10#include "mojo/public/cpp/bindings/error_handler.h"
11#include "mojo/public/cpp/bindings/interface_ptr.h"
12#include "mojo/public/cpp/system/core.h"
13#include "mojo/services/test_service/test_service.mojom.h"
14#include "testing/gtest/include/gtest/gtest.h"
15#include "url/gurl.h"
16
17namespace mojo {
18namespace shell {
19namespace test {
20namespace {
21
22typedef ShellTestBase ShellTestBaseTest;
23
24class QuitMessageLoopErrorHandler : public ErrorHandler {
25 public:
26  QuitMessageLoopErrorHandler() {}
27  virtual ~QuitMessageLoopErrorHandler() {}
28
29  // |ErrorHandler| implementation:
30  virtual void OnConnectionError() OVERRIDE {
31    base::MessageLoop::current()->QuitWhenIdle();
32  }
33
34 private:
35  DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
36};
37
38void PingCallback(base::MessageLoop* message_loop, bool* was_run) {
39  *was_run = true;
40  VLOG(2) << "Ping callback";
41  message_loop->QuitWhenIdle();
42}
43
44TEST_F(ShellTestBaseTest, LaunchServiceInProcess) {
45  InitMojo();
46
47  InterfacePtr<mojo::test::ITestService> test_service;
48
49  {
50    MessagePipe mp;
51    test_service.Bind(mp.handle0.Pass());
52    LaunchServiceInProcess(GURL("mojo:mojo_test_service"),
53                           mojo::test::ITestService::Name_,
54                           mp.handle1.Pass());
55  }
56
57  bool was_run = false;
58  test_service->Ping(base::Bind(&PingCallback,
59                                base::Unretained(message_loop()),
60                                base::Unretained(&was_run)));
61  message_loop()->Run();
62  EXPECT_TRUE(was_run);
63  EXPECT_FALSE(test_service.encountered_error());
64
65  test_service.reset();
66
67  // This will run until the test service has actually quit (which it will,
68  // since we killed the only connection to it).
69  message_loop()->Run();
70}
71
72// Tests that launching a service in process fails properly if the service
73// doesn't exist.
74TEST_F(ShellTestBaseTest, LaunchServiceInProcessInvalidService) {
75  InitMojo();
76
77  InterfacePtr<mojo::test::ITestService> test_service;
78
79  {
80    MessagePipe mp;
81    test_service.Bind(mp.handle0.Pass());
82    LaunchServiceInProcess(GURL("mojo:non_existent_service"),
83                           mojo::test::ITestService::Name_,
84                           mp.handle1.Pass());
85  }
86
87  bool was_run = false;
88  test_service->Ping(base::Bind(&PingCallback,
89                                base::Unretained(message_loop()),
90                                base::Unretained(&was_run)));
91
92  // This will quit because there's nothing running.
93  message_loop()->Run();
94  EXPECT_FALSE(was_run);
95
96  // It may have quit before an error was processed.
97  if (!test_service.encountered_error()) {
98    QuitMessageLoopErrorHandler quitter;
99    test_service.set_error_handler(&quitter);
100    message_loop()->Run();
101    EXPECT_TRUE(test_service.encountered_error());
102  }
103
104  test_service.reset();
105}
106
107}  // namespace
108}  // namespace test
109}  // namespace shell
110}  // namespace mojo
111