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

Side by Side Diff: mojo/shell/shell_test_base_unittest.cc

Issue 349303006: mojo: add some end-to-end shell tests and a new test sample app (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: no icu Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « mojo/shell/shell_test_base.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/shell/shell_test_base.h" 5 #include "mojo/shell/shell_test_base.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/i18n/time_formatting.h"
8 #include "base/macros.h" 9 #include "base/macros.h"
9 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/utf_string_conversions.h"
10 #include "mojo/public/cpp/bindings/error_handler.h" 12 #include "mojo/public/cpp/bindings/error_handler.h"
11 #include "mojo/public/cpp/bindings/interface_ptr.h" 13 #include "mojo/public/cpp/bindings/interface_ptr.h"
12 #include "mojo/public/cpp/system/core.h" 14 #include "mojo/public/cpp/system/core.h"
15 #include "mojo/services/test_service/test_request_tracker.mojom.h"
13 #include "mojo/services/test_service/test_service.mojom.h" 16 #include "mojo/services/test_service/test_service.mojom.h"
14 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
15 #include "url/gurl.h" 18 #include "url/gurl.h"
16 19
20 using mojo::test::ServiceReport;
21 using mojo::test::ServiceReportPtr;
22 using mojo::test::TestService;
23 using mojo::test::TestTimeService;
24 using mojo::test::TestServicePtr;
25 using mojo::test::TestTimeServicePtr;
26 using mojo::test::TestTrackedRequestService;
27 using mojo::test::TestTrackedRequestServicePtr;
28
17 namespace mojo { 29 namespace mojo {
18 namespace shell { 30 namespace shell {
19 namespace test { 31 namespace test {
20 namespace { 32 namespace {
21 33
22 typedef ShellTestBase ShellTestBaseTest; 34 void GetReportCallback(base::MessageLoop* loop,
35 std::vector<ServiceReport>* reports_out,
36 mojo::Array<ServiceReportPtr> report) {
37 for (size_t i = 0; i < report.size(); i++)
38 reports_out->push_back(*report[i]);
39 loop->QuitWhenIdle();
40 }
41
42 class ShellTestBaseTest : public ShellTestBase {
43 public:
44 // Convenience helpers for use as callbacks in tests.
45 template <typename T>
46 base::Callback<void()> SetAndQuit(T* val, T result) {
47 return base::Bind(&ShellTestBaseTest::SetAndQuitImpl<T>,
48 base::Unretained(this), val, result);
49 }
50 template <typename T>
51 base::Callback<void(T result)> SetAndQuit(T* val) {
52 return base::Bind(&ShellTestBaseTest::SetAndQuitImpl<T>,
53 base::Unretained(this), val);
54 }
55 static GURL test_app_url() {
56 return GURL("mojo:mojo_test_app");
57 }
58
59 void GetReport(std::vector<ServiceReport>* report) {
60 request_tracking_.Bind(
61 ConnectToService(GURL("mojo:mojo_test_request_tracker_app"),
62 TestTrackedRequestService::Name_).Pass());
63 request_tracking_->GetReport(base::Bind(&GetReportCallback,
64 base::Unretained(message_loop()),
65 base::Unretained(report)));
66 message_loop()->Run();
67 }
68
69 private:
70 template<typename T>
71 void SetAndQuitImpl(T* val, T result) {
72 *val = result;
73 message_loop()->QuitWhenIdle();
74 }
75 TestTrackedRequestServicePtr request_tracking_;
76 };
23 77
24 class QuitMessageLoopErrorHandler : public ErrorHandler { 78 class QuitMessageLoopErrorHandler : public ErrorHandler {
25 public: 79 public:
26 QuitMessageLoopErrorHandler() {} 80 QuitMessageLoopErrorHandler() {}
27 virtual ~QuitMessageLoopErrorHandler() {} 81 virtual ~QuitMessageLoopErrorHandler() {}
28 82
29 // |ErrorHandler| implementation: 83 // |ErrorHandler| implementation:
30 virtual void OnConnectionError() OVERRIDE { 84 virtual void OnConnectionError() OVERRIDE {
31 base::MessageLoop::current()->QuitWhenIdle(); 85 base::MessageLoop::current()->QuitWhenIdle();
32 } 86 }
33 87
34 private: 88 private:
35 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler); 89 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
36 }; 90 };
37 91
38 void PingCallback(base::MessageLoop* message_loop, bool* was_run) { 92 // Tests that we can connect to a single service within a single app.
39 *was_run = true; 93 TEST_F(ShellTestBaseTest, ConnectBasic) {
40 VLOG(2) << "Ping callback"; 94 InterfacePtr<TestService> service;
41 message_loop->QuitWhenIdle(); 95 service.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
42 }
43
44 TEST_F(ShellTestBaseTest, LaunchServiceInProcess) {
45 InterfacePtr<mojo::test::ITestService> test_service;
46
47 {
48 ScopedMessagePipeHandle service_handle =
49 LaunchServiceInProcess(GURL("mojo:mojo_test_service"),
50 mojo::test::ITestService::Name_);
51 test_service.Bind(service_handle.Pass());
52 }
53 96
54 bool was_run = false; 97 bool was_run = false;
55 test_service->Ping(base::Bind(&PingCallback, 98 service->Ping(SetAndQuit<bool>(&was_run, true));
56 base::Unretained(message_loop()),
57 base::Unretained(&was_run)));
58 message_loop()->Run(); 99 message_loop()->Run();
59 EXPECT_TRUE(was_run); 100 EXPECT_TRUE(was_run);
60 EXPECT_FALSE(test_service.encountered_error()); 101 EXPECT_FALSE(service.encountered_error());
61 102
62 test_service.reset(); 103 service.reset();
63 104
64 // This will run until the test service has actually quit (which it will, 105 // This will run until the test app has actually quit (which it will,
65 // since we killed the only connection to it). 106 // since we killed the only connection to it).
66 message_loop()->Run(); 107 message_loop()->Run();
67 } 108 }
68 109
69 // Tests that launching a service in process fails properly if the service 110 // Tests that trying to connect to a service fails properly if the service
70 // doesn't exist. 111 // doesn't exist.
71 TEST_F(ShellTestBaseTest, LaunchServiceInProcessInvalidService) { 112 TEST_F(ShellTestBaseTest, ConnectInvalidService) {
72 InterfacePtr<mojo::test::ITestService> test_service; 113 InterfacePtr<TestService> test_service;
73 114 test_service.Bind(ConnectToService(GURL("mojo:non_existent_service"),
74 { 115 TestService::Name_).Pass());
75 ScopedMessagePipeHandle service_handle =
76 LaunchServiceInProcess(GURL("mojo:non_existent_service"),
77 mojo::test::ITestService::Name_);
78 test_service.Bind(service_handle.Pass());
79 }
80 116
81 bool was_run = false; 117 bool was_run = false;
82 test_service->Ping(base::Bind(&PingCallback, 118 test_service->Ping(SetAndQuit<bool>(&was_run, true));
83 base::Unretained(message_loop()),
84 base::Unretained(&was_run)));
85 119
86 // This will quit because there's nothing running. 120 // This will quit because there's nothing running.
87 message_loop()->Run(); 121 message_loop()->Run();
88 EXPECT_FALSE(was_run); 122 EXPECT_FALSE(was_run);
89 123
90 // It may have quit before an error was processed. 124 // It may have quit before an error was processed.
91 if (!test_service.encountered_error()) { 125 if (!test_service.encountered_error()) {
92 QuitMessageLoopErrorHandler quitter; 126 QuitMessageLoopErrorHandler quitter;
93 test_service.set_error_handler(&quitter); 127 test_service.set_error_handler(&quitter);
94 message_loop()->Run(); 128 message_loop()->Run();
95 EXPECT_TRUE(test_service.encountered_error()); 129 EXPECT_TRUE(test_service.encountered_error());
96 } 130 }
97 131
98 test_service.reset(); 132 test_service.reset();
99 } 133 }
100 134
135 // Similar to ConnectBasic, but causes the app to instantiate multiple
136 // service implementation objects and verifies the shell can reach both.
137 TEST_F(ShellTestBaseTest, ConnectMultipleInstancesPerApp) {
138 {
139 TestServicePtr service1, service2;
140 service1.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
141 service2.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
142
143 bool was_run1 = false;
144 bool was_run2 = false;
145 service1->Ping(SetAndQuit<bool>(&was_run1, true));
146 message_loop()->Run();
147 service2->Ping(SetAndQuit<bool>(&was_run2, true));
148 message_loop()->Run();
149 EXPECT_TRUE(was_run1);
150 EXPECT_TRUE(was_run2);
151 EXPECT_FALSE(service1.encountered_error());
152 EXPECT_FALSE(service2.encountered_error());
153 }
154 message_loop()->Run();
155 }
156
157 // Tests that service A and service B, both in App 1, can talk to each other
158 // and parameters are passed around properly.
159 TEST_F(ShellTestBaseTest, ConnectDifferentServicesInSingleApp) {
160 // Have a TestService GetPartyTime on a TestTimeService in the same app.
161 int64 time_message;
162 TestServicePtr service;
163 service.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
164 service->ConnectToAppAndGetTime(test_app_url().spec(),
165 SetAndQuit<int64>(&time_message));
166 message_loop()->Run();
167
168 // Verify by hitting the TimeService directly.
169 TestTimeServicePtr time_service;
170 time_service.Bind(
171 ConnectToService(test_app_url(), TestTimeService::Name_).Pass());
172 int64 party_time;
173 time_service->GetPartyTime(SetAndQuit<int64>(&party_time));
174 message_loop()->Run();
175
176 EXPECT_EQ(time_message, party_time);
177 }
178
179 // Tests that a service A in App 1 can talk to service B in App 2 and
180 // parameters are passed around properly.
181 TEST_F(ShellTestBaseTest, ConnectDifferentServicesInDifferentApps) {
182 int64 time_message;
183 TestServicePtr service;
184 service.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
185 service->ConnectToAppAndGetTime("mojo:mojo_test_request_tracker_app",
186 SetAndQuit<int64>(&time_message));
187 message_loop()->Run();
188
189 // Verify by hitting the TimeService in the request tracker app directly.
190 TestTimeServicePtr time_service;
191 time_service.Bind(ConnectToService(GURL("mojo:mojo_test_request_tracker_app"),
192 TestTimeService::Name_).Pass());
193 int64 party_time;
194 time_service->GetPartyTime(SetAndQuit<int64>(&party_time));
195 message_loop()->Run();
196
197 EXPECT_EQ(time_message, party_time);
198 }
199
200 // Tests that service A in App 1 can be a client of service B in App 2.
201 TEST_F(ShellTestBaseTest, ConnectServiceAsClientOfSeparateApp) {
202 TestServicePtr service;
203 service.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
204 service->StartTrackingRequests(message_loop()->QuitWhenIdleClosure());
205 service->Ping(mojo::Callback<void()>());
206 message_loop()->Run();
207
208 for (int i = 0; i < 8; i++)
209 service->Ping(mojo::Callback<void()>());
210 service->Ping(message_loop()->QuitWhenIdleClosure());
211 message_loop()->Run();
212
213 // If everything worked properly, the tracking service should report
214 // 10 pings to TestService.
215 std::vector<ServiceReport> reports;
216 GetReport(&reports);
217 ASSERT_EQ(1U, reports.size());
218 EXPECT_EQ(TestService::Name_, reports[0].service_name);
219 EXPECT_EQ(10U, reports[0].total_requests);
220 }
221
222 // Connect several services together and use the tracking service to verify
223 // communication.
224 TEST_F(ShellTestBaseTest, ConnectManyClientsAndServices) {
225 TestServicePtr service;
226 TestTimeServicePtr time_service;
227
228 // Make a request to the TestService and have it contact TimeService in the
229 // tracking app. Do all this with tracking enabled, meaning both services
230 // are connected as clients of the TrackedRequestService.
231 service.Bind(ConnectToService(test_app_url(), TestService::Name_).Pass());
232 service->StartTrackingRequests(message_loop()->QuitWhenIdleClosure());
233 message_loop()->Run();
234 for (int i = 0; i < 5; i++)
235 service->Ping(mojo::Callback<void()>());
236 int64 time_result;
237 service->ConnectToAppAndGetTime("mojo:mojo_test_request_tracker_app",
238 SetAndQuit<int64>(&time_result));
239 message_loop()->Run();
240
241 // Also make a few requests to the TimeService in the test_app.
242 time_service.Bind(
243 ConnectToService(test_app_url(), TestTimeService::Name_).Pass());
244 time_service->StartTrackingRequests(message_loop()->QuitWhenIdleClosure());
245 time_service->GetPartyTime(mojo::Callback<void(uint64_t)>());
246 message_loop()->Run();
247 for (int i = 0; i < 18; i++)
248 time_service->GetPartyTime(mojo::Callback<void(uint64_t)>());
249 // Flush the tasks with one more to quit.
250 int64 party_time = 0;
251 time_service->GetPartyTime(SetAndQuit<int64>(&party_time));
252 message_loop()->Run();
253
254 std::vector<ServiceReport> reports;
255 GetReport(&reports);
256 ASSERT_EQ(3U, reports.size());
257 EXPECT_EQ(TestService::Name_, reports[0].service_name);
258 EXPECT_EQ(6U, reports[0].total_requests);
259 EXPECT_EQ(TestTimeService::Name_, reports[1].service_name);
260 EXPECT_EQ(1U, reports[1].total_requests);
261 EXPECT_EQ(TestTimeService::Name_, reports[2].service_name);
262 EXPECT_EQ(20U, reports[2].total_requests);
263 }
264
101 } // namespace 265 } // namespace
102 } // namespace test 266 } // namespace test
103 } // namespace shell 267 } // namespace shell
104 } // namespace mojo 268 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/shell_test_base.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698