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

Side by Side Diff: mojo/shell/application_manager/application_manager_unittest.cc

Issue 1049993002: Get mojo_shell building inside chromium checkout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix presubmit Created 5 years, 8 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
OLDNEW
(Empty)
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 "base/at_exit.h"
6 #include "base/bind.h"
7 #include "base/macros.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop/message_loop.h"
10 #include "mojo/public/cpp/application/application_connection.h"
11 #include "mojo/public/cpp/application/application_delegate.h"
12 #include "mojo/public/cpp/application/application_impl.h"
13 #include "mojo/public/cpp/application/interface_factory.h"
14 #include "mojo/public/cpp/bindings/strong_binding.h"
15 #include "mojo/public/interfaces/application/service_provider.mojom.h"
16 #include "mojo/shell/application_manager/application_loader.h"
17 #include "mojo/shell/application_manager/application_manager.h"
18 #include "mojo/shell/application_manager/test.mojom.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace mojo {
22 namespace shell {
23 namespace {
24
25 const char kTestURLString[] = "test:testService";
26 const char kTestAURLString[] = "test:TestA";
27 const char kTestBURLString[] = "test:TestB";
28
29 struct TestContext {
30 TestContext() : num_impls(0), num_loader_deletes(0) {}
31 std::string last_test_string;
32 int num_impls;
33 int num_loader_deletes;
34 };
35
36 void QuitClosure(bool* value) {
37 *value = true;
38 base::MessageLoop::current()->QuitWhenIdle();
39 }
40
41 class QuitMessageLoopErrorHandler : public ErrorHandler {
42 public:
43 QuitMessageLoopErrorHandler() {}
44 ~QuitMessageLoopErrorHandler() override {}
45
46 // |ErrorHandler| implementation:
47 void OnConnectionError() override {
48 base::MessageLoop::current()->QuitWhenIdle();
49 }
50
51 private:
52 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
53 };
54
55 class TestServiceImpl : public TestService {
56 public:
57 TestServiceImpl(TestContext* context, InterfaceRequest<TestService> request)
58 : context_(context), binding_(this, request.Pass()) {
59 ++context_->num_impls;
60 }
61
62 ~TestServiceImpl() override {
63 --context_->num_impls;
64 if (!base::MessageLoop::current()->is_running())
65 return;
66 base::MessageLoop::current()->Quit();
67 }
68
69 // TestService implementation:
70 void Test(const String& test_string,
71 const Callback<void()>& callback) override {
72 context_->last_test_string = test_string;
73 callback.Run();
74 }
75
76 private:
77 TestContext* context_;
78 StrongBinding<TestService> binding_;
79 };
80
81 class TestClient {
82 public:
83 explicit TestClient(TestServicePtr service)
84 : service_(service.Pass()), quit_after_ack_(false) {}
85
86 void AckTest() {
87 if (quit_after_ack_)
88 base::MessageLoop::current()->Quit();
89 }
90
91 void Test(const std::string& test_string) {
92 quit_after_ack_ = true;
93 service_->Test(test_string,
94 base::Bind(&TestClient::AckTest, base::Unretained(this)));
95 }
96
97 private:
98 TestServicePtr service_;
99 bool quit_after_ack_;
100 DISALLOW_COPY_AND_ASSIGN(TestClient);
101 };
102
103 class TestApplicationLoader : public ApplicationLoader,
104 public ApplicationDelegate,
105 public InterfaceFactory<TestService> {
106 public:
107 TestApplicationLoader() : context_(nullptr), num_loads_(0) {}
108
109 ~TestApplicationLoader() override {
110 if (context_)
111 ++context_->num_loader_deletes;
112 test_app_.reset();
113 }
114
115 void set_context(TestContext* context) { context_ = context; }
116 int num_loads() const { return num_loads_; }
117 const std::vector<std::string>& GetArgs() const { return test_app_->args(); }
118
119 private:
120 // ApplicationLoader implementation.
121 void Load(const GURL& url,
122 InterfaceRequest<Application> application_request) override {
123 ++num_loads_;
124 test_app_.reset(new ApplicationImpl(this, application_request.Pass()));
125 }
126
127 // ApplicationDelegate implementation.
128 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
129 connection->AddService(this);
130 return true;
131 }
132
133 // InterfaceFactory implementation.
134 void Create(ApplicationConnection* connection,
135 InterfaceRequest<TestService> request) override {
136 new TestServiceImpl(context_, request.Pass());
137 }
138
139 scoped_ptr<ApplicationImpl> test_app_;
140 TestContext* context_;
141 int num_loads_;
142 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
143 };
144
145 class ClosingApplicationLoader : public ApplicationLoader {
146 private:
147 // ApplicationLoader implementation.
148 void Load(const GURL& url,
149 InterfaceRequest<Application> application_request) override {}
150 };
151
152 class TesterContext {
153 public:
154 explicit TesterContext(base::MessageLoop* loop)
155 : num_b_calls_(0),
156 num_c_calls_(0),
157 num_a_deletes_(0),
158 num_b_deletes_(0),
159 num_c_deletes_(0),
160 tester_called_quit_(false),
161 a_called_quit_(false),
162 loop_(loop) {}
163
164 void IncrementNumBCalls() {
165 base::AutoLock lock(lock_);
166 num_b_calls_++;
167 }
168
169 void IncrementNumCCalls() {
170 base::AutoLock lock(lock_);
171 num_c_calls_++;
172 }
173
174 void IncrementNumADeletes() {
175 base::AutoLock lock(lock_);
176 num_a_deletes_++;
177 }
178
179 void IncrementNumBDeletes() {
180 base::AutoLock lock(lock_);
181 num_b_deletes_++;
182 }
183
184 void IncrementNumCDeletes() {
185 base::AutoLock lock(lock_);
186 num_c_deletes_++;
187 }
188
189 void set_tester_called_quit() {
190 base::AutoLock lock(lock_);
191 tester_called_quit_ = true;
192 }
193
194 void set_a_called_quit() {
195 base::AutoLock lock(lock_);
196 a_called_quit_ = true;
197 }
198
199 int num_b_calls() {
200 base::AutoLock lock(lock_);
201 return num_b_calls_;
202 }
203 int num_c_calls() {
204 base::AutoLock lock(lock_);
205 return num_c_calls_;
206 }
207 int num_a_deletes() {
208 base::AutoLock lock(lock_);
209 return num_a_deletes_;
210 }
211 int num_b_deletes() {
212 base::AutoLock lock(lock_);
213 return num_b_deletes_;
214 }
215 int num_c_deletes() {
216 base::AutoLock lock(lock_);
217 return num_c_deletes_;
218 }
219 bool tester_called_quit() {
220 base::AutoLock lock(lock_);
221 return tester_called_quit_;
222 }
223 bool a_called_quit() {
224 base::AutoLock lock(lock_);
225 return a_called_quit_;
226 }
227
228 void QuitSoon() {
229 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
230 }
231
232 private:
233 // lock_ protects all members except for loop_ which must be unchanged for the
234 // lifetime of this class.
235 base::Lock lock_;
236 int num_b_calls_;
237 int num_c_calls_;
238 int num_a_deletes_;
239 int num_b_deletes_;
240 int num_c_deletes_;
241 bool tester_called_quit_;
242 bool a_called_quit_;
243
244 base::MessageLoop* loop_;
245 };
246
247 // Used to test that the requestor url will be correctly passed.
248 class TestAImpl : public TestA {
249 public:
250 TestAImpl(ApplicationImpl* app_impl,
251 TesterContext* test_context,
252 InterfaceRequest<TestA> request)
253 : test_context_(test_context), binding_(this, request.Pass()) {
254 app_impl->ConnectToApplication(kTestBURLString)->ConnectToService(&b_);
255 }
256
257 ~TestAImpl() override {
258 test_context_->IncrementNumADeletes();
259 if (base::MessageLoop::current()->is_running())
260 Quit();
261 }
262
263 private:
264 void CallB() override {
265 b_->B(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
266 }
267
268 void CallCFromB() override {
269 b_->CallC(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
270 }
271
272 void Quit() {
273 base::MessageLoop::current()->Quit();
274 test_context_->set_a_called_quit();
275 test_context_->QuitSoon();
276 }
277
278 TesterContext* test_context_;
279 TestBPtr b_;
280 StrongBinding<TestA> binding_;
281 };
282
283 class TestBImpl : public TestB {
284 public:
285 TestBImpl(ApplicationConnection* connection,
286 TesterContext* test_context,
287 InterfaceRequest<TestB> request)
288 : test_context_(test_context), binding_(this, request.Pass()) {
289 connection->ConnectToService(&c_);
290 }
291
292 ~TestBImpl() override {
293 test_context_->IncrementNumBDeletes();
294 if (base::MessageLoop::current()->is_running())
295 base::MessageLoop::current()->Quit();
296 test_context_->QuitSoon();
297 }
298
299 private:
300 void B(const Callback<void()>& callback) override {
301 test_context_->IncrementNumBCalls();
302 callback.Run();
303 }
304
305 void CallC(const Callback<void()>& callback) override {
306 test_context_->IncrementNumBCalls();
307 c_->C(callback);
308 }
309
310 TesterContext* test_context_;
311 TestCPtr c_;
312 StrongBinding<TestB> binding_;
313 };
314
315 class TestCImpl : public TestC {
316 public:
317 TestCImpl(ApplicationConnection* connection,
318 TesterContext* test_context,
319 InterfaceRequest<TestC> request)
320 : test_context_(test_context), binding_(this, request.Pass()) {}
321
322 ~TestCImpl() override { test_context_->IncrementNumCDeletes(); }
323
324 private:
325 void C(const Callback<void()>& callback) override {
326 test_context_->IncrementNumCCalls();
327 callback.Run();
328 }
329
330 TesterContext* test_context_;
331 StrongBinding<TestC> binding_;
332 };
333
334 class Tester : public ApplicationDelegate,
335 public ApplicationLoader,
336 public InterfaceFactory<TestA>,
337 public InterfaceFactory<TestB>,
338 public InterfaceFactory<TestC> {
339 public:
340 Tester(TesterContext* context, const std::string& requestor_url)
341 : context_(context), requestor_url_(requestor_url) {}
342 ~Tester() override {}
343
344 private:
345 void Load(const GURL& url,
346 InterfaceRequest<Application> application_request) override {
347 app_.reset(new ApplicationImpl(this, application_request.Pass()));
348 }
349
350 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
351 if (!requestor_url_.empty() &&
352 requestor_url_ != connection->GetRemoteApplicationURL()) {
353 context_->set_tester_called_quit();
354 context_->QuitSoon();
355 base::MessageLoop::current()->Quit();
356 return false;
357 }
358 // If we're coming from A, then add B, otherwise A.
359 if (connection->GetRemoteApplicationURL() == kTestAURLString)
360 connection->AddService<TestB>(this);
361 else
362 connection->AddService<TestA>(this);
363 return true;
364 }
365
366 bool ConfigureOutgoingConnection(ApplicationConnection* connection) override {
367 // If we're connecting to B, then add C.
368 if (connection->GetRemoteApplicationURL() == kTestBURLString)
369 connection->AddService<TestC>(this);
370 return true;
371 }
372
373 void Create(ApplicationConnection* connection,
374 InterfaceRequest<TestA> request) override {
375 a_bindings_.push_back(new TestAImpl(app_.get(), context_, request.Pass()));
376 }
377
378 void Create(ApplicationConnection* connection,
379 InterfaceRequest<TestB> request) override {
380 new TestBImpl(connection, context_, request.Pass());
381 }
382
383 void Create(ApplicationConnection* connection,
384 InterfaceRequest<TestC> request) override {
385 new TestCImpl(connection, context_, request.Pass());
386 }
387
388 TesterContext* context_;
389 scoped_ptr<ApplicationImpl> app_;
390 std::string requestor_url_;
391 ScopedVector<TestAImpl> a_bindings_;
392 };
393
394 class TestDelegate : public ApplicationManager::Delegate {
395 public:
396 void AddMapping(const GURL& from, const GURL& to) { mappings_[from] = to; }
397
398 // ApplicationManager::Delegate
399 GURL ResolveMappings(const GURL& url) override {
400 auto it = mappings_.find(url);
401 if (it != mappings_.end())
402 return it->second;
403 return url;
404 }
405
406 // ApplicationManager::Delegate
407 GURL ResolveURL(const GURL& url) override {
408 GURL mapped_url = ResolveMappings(url);
409 // The shell automatically map mojo URLs.
410 if (mapped_url.scheme() == "mojo") {
411 url::Replacements<char> replacements;
412 replacements.SetScheme("file", url::Component(0, 4));
413 mapped_url = mapped_url.ReplaceComponents(replacements);
414 }
415 return mapped_url;
416 }
417
418 private:
419 std::map<GURL, GURL> mappings_;
420 };
421
422 class TestExternal : public ApplicationDelegate {
423 public:
424 TestExternal() : configure_incoming_connection_called_(false) {}
425
426 void Initialize(ApplicationImpl* app) override {
427 initialize_args_ = app->args();
428 base::MessageLoop::current()->Quit();
429 }
430
431 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
432 configure_incoming_connection_called_ = true;
433 base::MessageLoop::current()->Quit();
434 return true;
435 }
436
437 const std::vector<std::string>& initialize_args() const {
438 return initialize_args_;
439 }
440
441 bool configure_incoming_connection_called() const {
442 return configure_incoming_connection_called_;
443 }
444
445 private:
446 std::vector<std::string> initialize_args_;
447 bool configure_incoming_connection_called_;
448 };
449
450 class ApplicationManagerTest : public testing::Test {
451 public:
452 ApplicationManagerTest() : tester_context_(&loop_) {}
453
454 ~ApplicationManagerTest() override {}
455
456 void SetUp() override {
457 application_manager_.reset(new ApplicationManager(&test_delegate_));
458 test_loader_ = new TestApplicationLoader;
459 test_loader_->set_context(&context_);
460 application_manager_->set_default_loader(
461 scoped_ptr<ApplicationLoader>(test_loader_));
462
463 TestServicePtr service_proxy;
464 application_manager_->ConnectToService(GURL(kTestURLString),
465 &service_proxy);
466 test_client_.reset(new TestClient(service_proxy.Pass()));
467 }
468
469 void TearDown() override {
470 test_client_.reset();
471 application_manager_.reset();
472 }
473
474 void AddLoaderForURL(const GURL& url, const std::string& requestor_url) {
475 application_manager_->SetLoaderForURL(
476 make_scoped_ptr(new Tester(&tester_context_, requestor_url)), url);
477 }
478
479 bool HasFactoryForTestURL() {
480 ApplicationManager::TestAPI manager_test_api(application_manager_.get());
481 return manager_test_api.HasFactoryForURL(GURL(kTestURLString));
482 }
483
484 protected:
485 base::ShadowingAtExitManager at_exit_;
486 TestDelegate test_delegate_;
487 TestApplicationLoader* test_loader_;
488 TesterContext tester_context_;
489 TestContext context_;
490 base::MessageLoop loop_;
491 scoped_ptr<TestClient> test_client_;
492 scoped_ptr<ApplicationManager> application_manager_;
493 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest);
494 };
495
496 TEST_F(ApplicationManagerTest, Basic) {
497 test_client_->Test("test");
498 loop_.Run();
499 EXPECT_EQ(std::string("test"), context_.last_test_string);
500 }
501
502 // Confirm that no arguments are sent to an application by default.
503 TEST_F(ApplicationManagerTest, NoArgs) {
504 ApplicationManager am(&test_delegate_);
505 GURL test_url("test:test");
506 TestApplicationLoader* loader = new TestApplicationLoader;
507 loader->set_context(&context_);
508 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url);
509 TestServicePtr test_service;
510 am.ConnectToService(test_url, &test_service);
511 TestClient test_client(test_service.Pass());
512 test_client.Test("test");
513 loop_.Run();
514 std::vector<std::string> app_args = loader->GetArgs();
515 EXPECT_EQ(0U, app_args.size());
516 }
517
518 // Confirm that arguments are sent to an application.
519 TEST_F(ApplicationManagerTest, Args) {
520 ApplicationManager am(&test_delegate_);
521 GURL test_url("test:test");
522 std::vector<std::string> args;
523 args.push_back("test_arg1");
524 args.push_back("test_arg2");
525 am.SetArgsForURL(args, test_url);
526 TestApplicationLoader* loader = new TestApplicationLoader;
527 loader->set_context(&context_);
528 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url);
529 TestServicePtr test_service;
530 am.ConnectToService(test_url, &test_service);
531 TestClient test_client(test_service.Pass());
532 test_client.Test("test");
533 loop_.Run();
534 std::vector<std::string> app_args = loader->GetArgs();
535 ASSERT_EQ(args.size(), app_args.size());
536 EXPECT_EQ(args[0], app_args[0]);
537 EXPECT_EQ(args[1], app_args[1]);
538 }
539
540 // Confirm that arguments are aggregated through mappings.
541 TEST_F(ApplicationManagerTest, ArgsAndMapping) {
542 ApplicationManager am(&test_delegate_);
543 GURL test_url("test:test");
544 GURL test_url2("test:test2");
545 test_delegate_.AddMapping(test_url, test_url2);
546 std::vector<std::string> args;
547 args.push_back("test_arg1");
548 args.push_back("test_arg2");
549 am.SetArgsForURL(args, test_url);
550 std::vector<std::string> args2;
551 args2.push_back("test_arg3");
552 args2.push_back("test_arg4");
553 am.SetArgsForURL(args2, test_url2);
554 TestApplicationLoader* loader = new TestApplicationLoader;
555 loader->set_context(&context_);
556 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url2);
557 {
558 // Connext to the mapped url
559 TestServicePtr test_service;
560 am.ConnectToService(test_url, &test_service);
561 TestClient test_client(test_service.Pass());
562 test_client.Test("test");
563 loop_.Run();
564 std::vector<std::string> app_args = loader->GetArgs();
565 ASSERT_EQ(args.size() + args2.size(), app_args.size());
566 EXPECT_EQ(args[0], app_args[0]);
567 EXPECT_EQ(args[1], app_args[1]);
568 EXPECT_EQ(args2[0], app_args[2]);
569 EXPECT_EQ(args2[1], app_args[3]);
570 }
571 {
572 // Connext to the target url
573 TestServicePtr test_service;
574 am.ConnectToService(test_url2, &test_service);
575 TestClient test_client(test_service.Pass());
576 test_client.Test("test");
577 loop_.Run();
578 std::vector<std::string> app_args = loader->GetArgs();
579 ASSERT_EQ(args.size() + args2.size(), app_args.size());
580 EXPECT_EQ(args[0], app_args[0]);
581 EXPECT_EQ(args[1], app_args[1]);
582 EXPECT_EQ(args2[0], app_args[2]);
583 EXPECT_EQ(args2[1], app_args[3]);
584 }
585 }
586
587 TEST_F(ApplicationManagerTest, ClientError) {
588 test_client_->Test("test");
589 EXPECT_TRUE(HasFactoryForTestURL());
590 loop_.Run();
591 EXPECT_EQ(1, context_.num_impls);
592 test_client_.reset();
593 loop_.Run();
594 EXPECT_EQ(0, context_.num_impls);
595 EXPECT_TRUE(HasFactoryForTestURL());
596 }
597
598 TEST_F(ApplicationManagerTest, Deletes) {
599 {
600 ApplicationManager am(&test_delegate_);
601 TestApplicationLoader* default_loader = new TestApplicationLoader;
602 default_loader->set_context(&context_);
603 TestApplicationLoader* url_loader1 = new TestApplicationLoader;
604 TestApplicationLoader* url_loader2 = new TestApplicationLoader;
605 url_loader1->set_context(&context_);
606 url_loader2->set_context(&context_);
607 TestApplicationLoader* scheme_loader1 = new TestApplicationLoader;
608 TestApplicationLoader* scheme_loader2 = new TestApplicationLoader;
609 scheme_loader1->set_context(&context_);
610 scheme_loader2->set_context(&context_);
611 am.set_default_loader(scoped_ptr<ApplicationLoader>(default_loader));
612 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader1),
613 GURL("test:test1"));
614 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader2),
615 GURL("test:test1"));
616 am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader1),
617 "test");
618 am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader2),
619 "test");
620 }
621 EXPECT_EQ(5, context_.num_loader_deletes);
622 }
623
624 // Confirm that both urls and schemes can have their loaders explicitly set.
625 TEST_F(ApplicationManagerTest, SetLoaders) {
626 TestApplicationLoader* default_loader = new TestApplicationLoader;
627 TestApplicationLoader* url_loader = new TestApplicationLoader;
628 TestApplicationLoader* scheme_loader = new TestApplicationLoader;
629 application_manager_->set_default_loader(
630 scoped_ptr<ApplicationLoader>(default_loader));
631 application_manager_->SetLoaderForURL(
632 scoped_ptr<ApplicationLoader>(url_loader), GURL("test:test1"));
633 application_manager_->SetLoaderForScheme(
634 scoped_ptr<ApplicationLoader>(scheme_loader), "test");
635
636 // test::test1 should go to url_loader.
637 TestServicePtr test_service;
638 application_manager_->ConnectToService(GURL("test:test1"), &test_service);
639 EXPECT_EQ(1, url_loader->num_loads());
640 EXPECT_EQ(0, scheme_loader->num_loads());
641 EXPECT_EQ(0, default_loader->num_loads());
642
643 // test::test2 should go to scheme loader.
644 application_manager_->ConnectToService(GURL("test:test2"), &test_service);
645 EXPECT_EQ(1, url_loader->num_loads());
646 EXPECT_EQ(1, scheme_loader->num_loads());
647 EXPECT_EQ(0, default_loader->num_loads());
648
649 // http::test1 should go to default loader.
650 application_manager_->ConnectToService(GURL("http:test1"), &test_service);
651 EXPECT_EQ(1, url_loader->num_loads());
652 EXPECT_EQ(1, scheme_loader->num_loads());
653 EXPECT_EQ(1, default_loader->num_loads());
654 }
655
656 // Confirm that the url of a service is correctly passed to another service that
657 // it loads.
658 TEST_F(ApplicationManagerTest, ACallB) {
659 // Any url can load a.
660 AddLoaderForURL(GURL(kTestAURLString), std::string());
661
662 // Only a can load b.
663 AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
664
665 TestAPtr a;
666 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
667 a->CallB();
668 loop_.Run();
669 EXPECT_EQ(1, tester_context_.num_b_calls());
670 EXPECT_TRUE(tester_context_.a_called_quit());
671 }
672
673 // A calls B which calls C.
674 TEST_F(ApplicationManagerTest, BCallC) {
675 // Any url can load a.
676 AddLoaderForURL(GURL(kTestAURLString), std::string());
677
678 // Only a can load b.
679 AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
680
681 TestAPtr a;
682 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
683 a->CallCFromB();
684 loop_.Run();
685
686 EXPECT_EQ(1, tester_context_.num_b_calls());
687 EXPECT_EQ(1, tester_context_.num_c_calls());
688 EXPECT_TRUE(tester_context_.a_called_quit());
689 }
690
691 // Confirm that a service impl will be deleted if the app that connected to
692 // it goes away.
693 TEST_F(ApplicationManagerTest, BDeleted) {
694 AddLoaderForURL(GURL(kTestAURLString), std::string());
695 AddLoaderForURL(GURL(kTestBURLString), std::string());
696
697 TestAPtr a;
698 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
699
700 a->CallB();
701 loop_.Run();
702
703 // Kills the a app.
704 application_manager_->SetLoaderForURL(scoped_ptr<ApplicationLoader>(),
705 GURL(kTestAURLString));
706 loop_.Run();
707
708 EXPECT_EQ(1, tester_context_.num_b_deletes());
709 }
710
711 // Confirm that the url of a service is correctly passed to another service that
712 // it loads, and that it can be rejected.
713 TEST_F(ApplicationManagerTest, ANoLoadB) {
714 // Any url can load a.
715 AddLoaderForURL(GURL(kTestAURLString), std::string());
716
717 // Only c can load b, so this will fail.
718 AddLoaderForURL(GURL(kTestBURLString), "test:TestC");
719
720 TestAPtr a;
721 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
722 a->CallB();
723 loop_.Run();
724 EXPECT_EQ(0, tester_context_.num_b_calls());
725
726 EXPECT_FALSE(tester_context_.a_called_quit());
727 EXPECT_TRUE(tester_context_.tester_called_quit());
728 }
729
730 TEST_F(ApplicationManagerTest, NoServiceNoLoad) {
731 AddLoaderForURL(GURL(kTestAURLString), std::string());
732
733 // There is no TestC service implementation registered with
734 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
735 TestCPtr c;
736 application_manager_->ConnectToService(GURL(kTestAURLString), &c);
737 QuitMessageLoopErrorHandler quitter;
738 c.set_error_handler(&quitter);
739
740 loop_.Run();
741 EXPECT_TRUE(c.encountered_error());
742 }
743
744 TEST_F(ApplicationManagerTest, MappedURLsShouldNotCauseDuplicateLoad) {
745 test_delegate_.AddMapping(GURL("foo:foo2"), GURL("foo:foo"));
746 // 1 because ApplicationManagerTest connects once at startup.
747 EXPECT_EQ(1, test_loader_->num_loads());
748
749 TestServicePtr test_service;
750 application_manager_->ConnectToService(GURL("foo:foo"), &test_service);
751 EXPECT_EQ(2, test_loader_->num_loads());
752
753 TestServicePtr test_service2;
754 application_manager_->ConnectToService(GURL("foo:foo2"), &test_service2);
755 EXPECT_EQ(2, test_loader_->num_loads());
756
757 TestServicePtr test_service3;
758 application_manager_->ConnectToService(GURL("bar:bar"), &test_service2);
759 EXPECT_EQ(3, test_loader_->num_loads());
760 }
761
762 TEST_F(ApplicationManagerTest, MappedURLsShouldWorkWithLoaders) {
763 TestApplicationLoader* custom_loader = new TestApplicationLoader;
764 TestContext context;
765 custom_loader->set_context(&context);
766 application_manager_->SetLoaderForURL(make_scoped_ptr(custom_loader),
767 GURL("mojo:foo"));
768 test_delegate_.AddMapping(GURL("mojo:foo2"), GURL("mojo:foo"));
769
770 TestServicePtr test_service;
771 application_manager_->ConnectToService(GURL("mojo:foo2"), &test_service);
772 EXPECT_EQ(1, custom_loader->num_loads());
773 custom_loader->set_context(nullptr);
774 }
775
776 TEST_F(ApplicationManagerTest, ExternalApp) {
777 ApplicationPtr application;
778 TestExternal external;
779 std::vector<std::string> args;
780 args.push_back("test");
781 ApplicationImpl app(&external, GetProxy(&application));
782 application_manager_->RegisterExternalApplication(GURL("mojo:test"), args,
783 application.Pass());
784 loop_.Run();
785 EXPECT_EQ(args, external.initialize_args());
786 application_manager_->ConnectToServiceByName(GURL("mojo:test"),
787 std::string());
788 loop_.Run();
789 EXPECT_TRUE(external.configure_incoming_connection_called());
790 };
791
792 TEST_F(ApplicationManagerTest, TestQueryWithLoaders) {
793 TestApplicationLoader* url_loader = new TestApplicationLoader;
794 TestApplicationLoader* scheme_loader = new TestApplicationLoader;
795 application_manager_->SetLoaderForURL(
796 scoped_ptr<ApplicationLoader>(url_loader), GURL("test:test1"));
797 application_manager_->SetLoaderForScheme(
798 scoped_ptr<ApplicationLoader>(scheme_loader), "test");
799
800 // test::test1 should go to url_loader.
801 TestServicePtr test_service;
802 application_manager_->ConnectToService(GURL("test:test1?foo=bar"),
803 &test_service);
804 EXPECT_EQ(1, url_loader->num_loads());
805 EXPECT_EQ(0, scheme_loader->num_loads());
806
807 // test::test2 should go to scheme loader.
808 application_manager_->ConnectToService(GURL("test:test2?foo=bar"),
809 &test_service);
810 EXPECT_EQ(1, url_loader->num_loads());
811 EXPECT_EQ(1, scheme_loader->num_loads());
812 }
813
814 TEST_F(ApplicationManagerTest, TestEndApplicationClosure) {
815 ClosingApplicationLoader* loader = new ClosingApplicationLoader();
816 application_manager_->SetLoaderForScheme(
817 scoped_ptr<ApplicationLoader>(loader), "test");
818
819 bool called = false;
820 application_manager_->ConnectToApplication(
821 GURL("test:test"), GURL(), nullptr, nullptr,
822 base::Bind(&QuitClosure, base::Unretained(&called)));
823 loop_.Run();
824 EXPECT_TRUE(called);
825 }
826
827 } // namespace
828 } // namespace shell
829 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/application_manager/application_manager.cc ('k') | mojo/shell/application_manager/data_pipe_peek.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698