OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/at_exit.h" | 5 #include "mojo/shell/capability_filter_test.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 "base/stl_util.h" | |
11 #include "base/strings/stringprintf.h" | |
12 #include "mojo/application/public/cpp/application_connection.h" | |
13 #include "mojo/application/public/cpp/application_delegate.h" | |
14 #include "mojo/application/public/cpp/application_impl.h" | |
15 #include "mojo/application/public/cpp/connect.h" | |
16 #include "mojo/application/public/cpp/interface_factory.h" | |
17 #include "mojo/application/public/cpp/service_provider_impl.h" | |
18 #include "mojo/application/public/interfaces/content_handler.mojom.h" | |
19 #include "mojo/common/weak_binding_set.h" | |
20 #include "mojo/public/cpp/bindings/strong_binding.h" | |
21 #include "mojo/shell/application_loader.h" | |
22 #include "mojo/shell/application_manager.h" | |
23 #include "mojo/shell/capability_filter_unittest.mojom.h" | |
24 #include "mojo/shell/test_package_manager.h" | 6 #include "mojo/shell/test_package_manager.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 7 #include "testing/gtest/include/gtest/gtest.h" |
26 | 8 |
27 namespace mojo { | 9 namespace mojo { |
28 namespace shell { | 10 namespace shell { |
29 namespace { | 11 namespace test { |
30 | 12 |
31 const char kTestMimeType[] = "test/mime-type"; | 13 class CapabilityFilterApplicationTest : public CapabilityFilterTest { |
32 | |
33 // Lives on the main thread of the test. | |
34 // Listens for services exposed/blocked and for application connections being | |
35 // closed. Quits |loop| when all expectations are met. | |
36 class ConnectionValidator : public ApplicationLoader, | |
37 public ApplicationDelegate, | |
38 public InterfaceFactory<Validator>, | |
39 public Validator { | |
40 public: | 14 public: |
41 ConnectionValidator(const std::set<std::string>& expectations, | 15 CapabilityFilterApplicationTest() {} |
42 base::MessageLoop* loop) | 16 ~CapabilityFilterApplicationTest() override {} |
43 : app_(nullptr), | |
44 expectations_(expectations), | |
45 loop_(loop) {} | |
46 ~ConnectionValidator() override {} | |
47 | |
48 bool expectations_met() { | |
49 return unexpected_.empty() && expectations_.empty(); | |
50 } | |
51 | |
52 void PrintUnmetExpectations() { | |
53 for (auto expectation : expectations_) | |
54 ADD_FAILURE() << "Unmet: " << expectation; | |
55 for (auto unexpected : unexpected_) | |
56 ADD_FAILURE() << "Unexpected: " << unexpected; | |
57 } | |
58 | |
59 private: | |
60 // Overridden from ApplicationLoader: | |
61 void Load(const GURL& url, InterfaceRequest<Application> request) override { | |
62 app_.reset(new ApplicationImpl(this, request.Pass())); | |
63 } | |
64 | |
65 // Overridden from ApplicationDelegate: | |
66 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | |
67 connection->AddService<Validator>(this); | |
68 return true; | |
69 } | |
70 | |
71 // Overridden from InterfaceFactory<Validator>: | |
72 void Create(ApplicationConnection* connection, | |
73 InterfaceRequest<Validator> request) override { | |
74 validator_bindings_.AddBinding(this, request.Pass()); | |
75 } | |
76 | |
77 // Overridden from Validator: | |
78 void AddServiceCalled(const String& app_url, | |
79 const String& service_url, | |
80 const String& name, | |
81 bool blocked) override { | |
82 Validate(base::StringPrintf("%s %s %s %s", | |
83 blocked ? "B" : "E", app_url.data(), service_url.data(), name.data())); | |
84 } | |
85 void ConnectionClosed(const String& app_url, | |
86 const String& service_url) override { | |
87 Validate(base::StringPrintf("C %s %s", app_url.data(), service_url.data())); | |
88 } | |
89 | |
90 void Validate(const std::string& result) { | |
91 DVLOG(1) << "Validate: " << result; | |
92 auto i = expectations_.find(result); | |
93 if (i != expectations_.end()) { | |
94 expectations_.erase(i); | |
95 if (expectations_.empty()) | |
96 loop_->Quit(); | |
97 } else { | |
98 // This is a test failure, and will result in PrintUnexpectedExpecations() | |
99 // being called. | |
100 unexpected_.insert(result); | |
101 loop_->Quit(); | |
102 } | |
103 } | |
104 | |
105 scoped_ptr<ApplicationImpl> app_; | |
106 std::set<std::string> expectations_; | |
107 std::set<std::string> unexpected_; | |
108 base::MessageLoop* loop_; | |
109 WeakBindingSet<Validator> validator_bindings_; | |
110 | |
111 DISALLOW_COPY_AND_ASSIGN(ConnectionValidator); | |
112 }; | |
113 | |
114 // This class models an application who will use the shell to interact with a | |
115 // system service. The shell may limit this application's visibility of the full | |
116 // set of interfaces exposed by that service. | |
117 class TestApplication : public ApplicationDelegate { | |
118 public: | |
119 TestApplication() : app_(nullptr) {} | |
120 ~TestApplication() override {} | |
121 | |
122 private: | |
123 // Overridden from ApplicationDelegate: | |
124 void Initialize(ApplicationImpl* app) override { | |
125 app_ = app; | |
126 } | |
127 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | |
128 // TestApplications receive their Validator via the inbound connection. | |
129 connection->ConnectToService(&validator_); | |
130 | |
131 URLRequestPtr request(URLRequest::New()); | |
132 request->url = String::From("test:service"); | |
133 connection1_ = app_->ConnectToApplication(request.Pass()); | |
134 connection1_->SetRemoteServiceProviderConnectionErrorHandler( | |
135 base::Bind(&TestApplication::ConnectionClosed, | |
136 base::Unretained(this), "test:service")); | |
137 | |
138 URLRequestPtr request2(URLRequest::New()); | |
139 request2->url = String::From("test:service2"); | |
140 connection2_ = app_->ConnectToApplication(request2.Pass()); | |
141 connection2_->SetRemoteServiceProviderConnectionErrorHandler( | |
142 base::Bind(&TestApplication::ConnectionClosed, | |
143 base::Unretained(this), "test:service2")); | |
144 return true; | |
145 } | |
146 | |
147 void ConnectionClosed(const std::string& service_url) { | |
148 validator_->ConnectionClosed(app_->url(), service_url); | |
149 } | |
150 | |
151 ApplicationImpl* app_; | |
152 ValidatorPtr validator_; | |
153 scoped_ptr<ApplicationConnection> connection1_; | |
154 scoped_ptr<ApplicationConnection> connection2_; | |
155 | |
156 DISALLOW_COPY_AND_ASSIGN(TestApplication); | |
157 }; | |
158 | |
159 class TestContentHandler : public ApplicationDelegate, | |
160 public InterfaceFactory<ContentHandler>, | |
161 public ContentHandler { | |
162 public: | |
163 TestContentHandler() : app_(nullptr) {} | |
164 ~TestContentHandler() override {} | |
165 | |
166 private: | |
167 // Overridden from ApplicationDelegate: | |
168 void Initialize(ApplicationImpl* app) override { | |
169 app_ = app; | |
170 } | |
171 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | |
172 connection->AddService<ContentHandler>(this); | |
173 return true; | |
174 } | |
175 | |
176 // Overridden from InterfaceFactory<ContentHandler>: | |
177 void Create(ApplicationConnection* connection, | |
178 InterfaceRequest<ContentHandler> request) override { | |
179 bindings_.AddBinding(this, request.Pass()); | |
180 } | |
181 | |
182 // Overridden from ContentHandler: | |
183 void StartApplication(InterfaceRequest<Application> application, | |
184 URLResponsePtr response) override { | |
185 scoped_ptr<ApplicationDelegate> delegate(new TestApplication); | |
186 embedded_apps_.push_back( | |
187 new ApplicationImpl(delegate.get(), application.Pass())); | |
188 embedded_app_delegates_.push_back(delegate.Pass()); | |
189 } | |
190 | |
191 ApplicationImpl* app_; | |
192 WeakBindingSet<ContentHandler> bindings_; | |
193 ScopedVector<ApplicationDelegate> embedded_app_delegates_; | |
194 ScopedVector<ApplicationImpl> embedded_apps_; | |
195 | |
196 DISALLOW_COPY_AND_ASSIGN(TestContentHandler); | |
197 }; | |
198 | |
199 // This class models a system service that exposes two interfaces, Safe and | |
200 // Unsafe. The interface Unsafe is not to be exposed to untrusted applications. | |
201 class ServiceApplication : public ApplicationDelegate, | |
202 public InterfaceFactory<Safe>, | |
203 public InterfaceFactory<Unsafe>, | |
204 public Safe, | |
205 public Unsafe { | |
206 public: | |
207 ServiceApplication() : app_(nullptr) {} | |
208 ~ServiceApplication() override {} | |
209 | |
210 private: | |
211 // Overridden from ApplicationDelegate: | |
212 void Initialize(ApplicationImpl* app) override { | |
213 app_ = app; | |
214 // ServiceApplications have no capability filter and can thus connect | |
215 // directly to the validator application. | |
216 URLRequestPtr request(URLRequest::New()); | |
217 request->url = String::From("test:validator"); | |
218 app_->ConnectToService(request.Pass(), &validator_); | |
219 } | |
220 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | |
221 AddService<Safe>(connection); | |
222 AddService<Unsafe>(connection); | |
223 return true; | |
224 } | |
225 | |
226 // Overridden from InterfaceFactory<Safe>: | |
227 void Create(ApplicationConnection* connection, | |
228 InterfaceRequest<Safe> request) override { | |
229 safe_bindings_.AddBinding(this, request.Pass()); | |
230 } | |
231 | |
232 // Overridden from InterfaceFactory<Unsafe>: | |
233 void Create(ApplicationConnection* connection, | |
234 InterfaceRequest<Unsafe> request) override { | |
235 unsafe_bindings_.AddBinding(this, request.Pass()); | |
236 } | |
237 | |
238 template <typename Interface> | |
239 void AddService(ApplicationConnection* connection) { | |
240 validator_->AddServiceCalled(connection->GetRemoteApplicationURL(), | |
241 connection->GetConnectionURL(), | |
242 Interface::Name_, | |
243 !connection->AddService<Interface>(this)); | |
244 } | |
245 | |
246 ApplicationImpl* app_; | |
247 ValidatorPtr validator_; | |
248 WeakBindingSet<Safe> safe_bindings_; | |
249 WeakBindingSet<Unsafe> unsafe_bindings_; | |
250 | |
251 DISALLOW_COPY_AND_ASSIGN(ServiceApplication); | |
252 }; | |
253 | |
254 // A custom Fetcher used to trigger a content handler for kTestMimeType for a | |
255 // specific test. | |
256 class TestFetcher : public Fetcher { | |
257 public: | |
258 TestFetcher(const GURL& url, const FetchCallback& callback) | |
259 : Fetcher(callback), | |
260 url_(url) { | |
261 loader_callback_.Run(make_scoped_ptr(this)); | |
262 } | |
263 ~TestFetcher() override {} | |
264 | |
265 private: | |
266 // Overridden from Fetcher: | |
267 const GURL& GetURL() const override { return url_; } | |
268 GURL GetRedirectURL() const override { return GURL(); } | |
269 GURL GetRedirectReferer() const override { return GURL(); } | |
270 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner, | |
271 uint32_t skip) override { | |
272 URLResponsePtr response(URLResponse::New()); | |
273 response->url = url_.spec(); | |
274 return response.Pass(); | |
275 } | |
276 void AsPath( | |
277 base::TaskRunner* task_runner, | |
278 base::Callback<void(const base::FilePath&, bool)> callback) override {} | |
279 std::string MimeType() override { return kTestMimeType; } | |
280 bool HasMojoMagic() override { return false; } | |
281 bool PeekFirstLine(std::string* line) override { return false; } | |
282 | |
283 const GURL url_; | |
284 | |
285 DISALLOW_COPY_AND_ASSIGN(TestFetcher); | |
286 }; | |
287 | |
288 class CFTestPackageManager : public TestPackageManager { | |
289 public: | |
290 CFTestPackageManager() {} | |
291 ~CFTestPackageManager() override {} | |
292 | |
293 void set_use_test_fetcher(bool use_test_fetcher) { | |
294 use_test_fetcher_ = use_test_fetcher; | |
295 } | |
296 | |
297 private: | |
298 // Overridden from TestPackageManager: | |
299 void FetchRequest(URLRequestPtr request, | |
300 const Fetcher::FetchCallback& loader_callback) override { | |
301 if (use_test_fetcher_) | |
302 new TestFetcher(GURL(request->url), loader_callback); | |
303 } | |
304 | |
305 bool use_test_fetcher_; | |
306 | |
307 DISALLOW_COPY_AND_ASSIGN(CFTestPackageManager); | |
308 }; | |
309 | |
310 class TestLoader : public ApplicationLoader { | |
311 public: | |
312 explicit TestLoader(ApplicationDelegate* delegate) : delegate_(delegate) {} | |
313 ~TestLoader() override {} | |
314 | |
315 private: | |
316 // Overridden from ApplicationLoader: | |
317 void Load(const GURL& url, InterfaceRequest<Application> request) override { | |
318 app_.reset(new ApplicationImpl(delegate_.get(), request.Pass())); | |
319 } | |
320 | |
321 scoped_ptr<ApplicationDelegate> delegate_; | |
322 scoped_ptr<ApplicationImpl> app_; | |
323 | |
324 DISALLOW_COPY_AND_ASSIGN(TestLoader); | |
325 }; | |
326 | |
327 class CapabilityFilterTest : public testing::Test { | |
328 public: | |
329 CapabilityFilterTest() | |
330 : test_package_manager_(nullptr), | |
331 validator_(nullptr) {} | |
332 ~CapabilityFilterTest() override {} | |
333 | |
334 protected: | |
335 void RunApplication(const std::string& url, const CapabilityFilter& filter) { | |
336 ServiceProviderPtr services; | |
337 | |
338 // We expose Validator to the test application via ConnectToApplication | |
339 // because we don't allow the test application to connect to test:validator. | |
340 // Adding it to the CapabilityFilter would interfere with the test. | |
341 ServiceProviderPtr exposed_services; | |
342 (new ServiceProviderImpl(GetProxy(&exposed_services)))-> | |
343 AddService<Validator>(validator_); | |
344 scoped_ptr<ConnectToApplicationParams> params( | |
345 new ConnectToApplicationParams); | |
346 params->SetTarget(Identity(GURL(url), std::string(), filter)); | |
347 params->set_services(GetProxy(&services)); | |
348 params->set_exposed_services(exposed_services.Pass()); | |
349 params->set_on_application_end(base::MessageLoop::QuitWhenIdleClosure()); | |
350 application_manager_->ConnectToApplication(params.Pass()); | |
351 } | |
352 | |
353 void InitValidator(const std::set<std::string>& expectations) { | |
354 validator_ = new ConnectionValidator(expectations, &loop_); | |
355 application_manager()->SetLoaderForURL(make_scoped_ptr(validator_), | |
356 GURL("test:validator")); | |
357 } | |
358 | |
359 template <class T> | |
360 void CreateLoader(const std::string& url) { | |
361 application_manager_->SetLoaderForURL( | |
362 make_scoped_ptr(new TestLoader(new T)), GURL(url)); | |
363 } | |
364 | |
365 virtual void RunTest() { | |
366 loop()->Run(); | |
367 EXPECT_TRUE(validator_->expectations_met()); | |
368 if (!validator_->expectations_met()) | |
369 validator_->PrintUnmetExpectations(); | |
370 } | |
371 | |
372 void RunContentHandlerTest() { | |
373 set_use_test_fetcher(); | |
374 | |
375 GURL content_handler_url("test:content_handler"); | |
376 test_package_manager_->RegisterContentHandler(kTestMimeType, | |
377 content_handler_url); | |
378 | |
379 CreateLoader<TestContentHandler>(content_handler_url.spec()); | |
380 RunTest(); | |
381 } | |
382 | |
383 base::MessageLoop* loop() { return &loop_; } | |
384 ApplicationManager* application_manager() { | |
385 return application_manager_.get(); | |
386 } | |
387 ConnectionValidator* validator() { return validator_; } | |
388 void set_use_test_fetcher() { | |
389 test_package_manager_->set_use_test_fetcher(true); | |
390 } | |
391 | |
392 // Overridden from testing::Test: | |
393 void SetUp() override { | |
394 test_package_manager_ = new CFTestPackageManager; | |
395 application_manager_.reset( | |
396 new ApplicationManager(make_scoped_ptr(test_package_manager_))); | |
397 CreateLoader<ServiceApplication>("test:service"); | |
398 CreateLoader<ServiceApplication>("test:service2"); | |
399 } | |
400 void TearDown() override { | |
401 test_package_manager_->set_use_test_fetcher(false); | |
402 application_manager_.reset(); | |
403 } | |
404 | |
405 private: | |
406 template<class T> | |
407 scoped_ptr<ApplicationDelegate> CreateApplicationDelegate() { | |
408 return scoped_ptr<ApplicationDelegate>(new T); | |
409 } | |
410 | |
411 CFTestPackageManager* test_package_manager_; | |
412 base::ShadowingAtExitManager at_exit_; | |
413 base::MessageLoop loop_; | |
414 scoped_ptr<ApplicationManager> application_manager_; | |
415 ConnectionValidator* validator_; | |
416 | |
417 DISALLOW_COPY_AND_ASSIGN(CapabilityFilterTest); | |
418 }; | |
419 | |
420 class CapabilityFilter_BlockingTest : public CapabilityFilterTest { | |
421 public: | |
422 CapabilityFilter_BlockingTest() {} | |
423 ~CapabilityFilter_BlockingTest() override {} | |
424 | |
425 protected: | |
426 void RunTest() override { | |
427 // This first application can only connect to test:service. Connections to | |
428 // test:service2 will be blocked. It also will only be able to see the | |
429 // "Safe" interface exposed by test:service. It will be blocked from seeing | |
430 // "Unsafe". | |
431 AllowedInterfaces interfaces; | |
432 interfaces.insert(Safe::Name_); | |
433 CapabilityFilter filter; | |
434 filter["test:service"] = interfaces; | |
435 RunApplication("test:untrusted", filter); | |
436 | |
437 // This second application can connect to both test:service and | |
438 // test:service2. It can connect to both "Safe" and "Unsafe" interfaces. | |
439 RunApplication("test:trusted", GetPermissiveCapabilityFilter()); | |
440 | |
441 CapabilityFilterTest::RunTest(); | |
442 } | |
443 | 17 |
444 private: | 18 private: |
445 // Overridden from CapabilityFilterTest: | 19 // Overridden from CapabilityFilterTest: |
446 void SetUp() override { | 20 PackageManager* CreatePackageManager() override { |
447 CapabilityFilterTest::SetUp(); | 21 return new TestPackageManager; |
448 | |
449 std::set<std::string> expectations; | |
450 expectations.insert("E test:trusted test:service mojo::shell::Safe"); | |
451 expectations.insert("E test:trusted test:service mojo::shell::Unsafe"); | |
452 expectations.insert("E test:trusted test:service2 mojo::shell::Safe"); | |
453 expectations.insert("E test:trusted test:service2 mojo::shell::Unsafe"); | |
454 expectations.insert("E test:untrusted test:service mojo::shell::Safe"); | |
455 expectations.insert("B test:untrusted test:service mojo::shell::Unsafe"); | |
456 expectations.insert("C test:untrusted test:service2"); | |
457 InitValidator(expectations); | |
458 } | 22 } |
459 | 23 |
460 DISALLOW_COPY_AND_ASSIGN(CapabilityFilter_BlockingTest); | 24 DISALLOW_COPY_AND_ASSIGN(CapabilityFilterApplicationTest); |
461 }; | 25 }; |
462 | 26 |
463 TEST_F(CapabilityFilter_BlockingTest, Application) { | 27 TEST_F(CapabilityFilterApplicationTest, Blocking) { |
464 CreateLoader<TestApplication>("test:trusted"); | 28 CreateLoader<TestApplication>("test:trusted"); |
465 CreateLoader<TestApplication>("test:untrusted"); | 29 CreateLoader<TestApplication>("test:untrusted"); |
466 RunTest(); | 30 RunBlockingTest(); |
467 } | 31 } |
468 | 32 |
469 TEST_F(CapabilityFilter_BlockingTest, ContentHandler) { | 33 TEST_F(CapabilityFilterApplicationTest, Wildcards) { |
470 RunContentHandlerTest(); | |
471 } | |
472 | |
473 class CapabilityFilter_WildcardsTest : public CapabilityFilterTest { | |
474 public: | |
475 CapabilityFilter_WildcardsTest() {} | |
476 ~CapabilityFilter_WildcardsTest() override {} | |
477 | |
478 protected: | |
479 void RunTest() override { | |
480 // This application is allowed to connect to any application because of a | |
481 // wildcard rule, and any interface exposed because of a wildcard rule in | |
482 // the interface array. | |
483 RunApplication("test:wildcard", GetPermissiveCapabilityFilter()); | |
484 | |
485 // This application is allowed to connect to no other applications because | |
486 // of an empty capability filter. | |
487 RunApplication("test:blocked", CapabilityFilter()); | |
488 | |
489 // This application is allowed to connect to any application because of a | |
490 // wildcard rule but may not connect to any interfaces because of an empty | |
491 // interface array. | |
492 CapabilityFilter filter1; | |
493 filter1["*"] = AllowedInterfaces(); | |
494 RunApplication("test:wildcard2", filter1); | |
495 | |
496 // This application is allowed to connect to both test:service and | |
497 // test:service2, and may see any interface exposed by test:service but only | |
498 // the Safe interface exposed by test:service2. | |
499 AllowedInterfaces interfaces2; | |
500 interfaces2.insert("*"); | |
501 CapabilityFilter filter2; | |
502 filter2["test:service"] = interfaces2; | |
503 AllowedInterfaces interfaces3; | |
504 interfaces3.insert(Safe::Name_); | |
505 filter2["test:service2"] = interfaces3; | |
506 RunApplication("test:wildcard3", filter2); | |
507 | |
508 CapabilityFilterTest::RunTest(); | |
509 } | |
510 | |
511 private: | |
512 // Overridden from CapabilityFilterTest: | |
513 void SetUp() override { | |
514 CapabilityFilterTest::SetUp(); | |
515 | |
516 std::set<std::string> expectations; | |
517 expectations.insert("E test:wildcard test:service mojo::shell::Safe"); | |
518 expectations.insert("E test:wildcard test:service mojo::shell::Unsafe"); | |
519 expectations.insert("E test:wildcard test:service2 mojo::shell::Safe"); | |
520 expectations.insert("E test:wildcard test:service2 mojo::shell::Unsafe"); | |
521 expectations.insert("C test:blocked test:service"); | |
522 expectations.insert("C test:blocked test:service2"); | |
523 expectations.insert("B test:wildcard2 test:service mojo::shell::Safe"); | |
524 expectations.insert("B test:wildcard2 test:service mojo::shell::Unsafe"); | |
525 expectations.insert("B test:wildcard2 test:service2 mojo::shell::Safe"); | |
526 expectations.insert("B test:wildcard2 test:service2 mojo::shell::Unsafe"); | |
527 expectations.insert("E test:wildcard3 test:service mojo::shell::Safe"); | |
528 expectations.insert("E test:wildcard3 test:service mojo::shell::Unsafe"); | |
529 expectations.insert("E test:wildcard3 test:service2 mojo::shell::Safe"); | |
530 expectations.insert("B test:wildcard3 test:service2 mojo::shell::Unsafe"); | |
531 InitValidator(expectations); | |
532 } | |
533 | |
534 DISALLOW_COPY_AND_ASSIGN(CapabilityFilter_WildcardsTest); | |
535 }; | |
536 | |
537 TEST_F(CapabilityFilter_WildcardsTest, Application) { | |
538 CreateLoader<TestApplication>("test:wildcard"); | 34 CreateLoader<TestApplication>("test:wildcard"); |
539 CreateLoader<TestApplication>("test:blocked"); | 35 CreateLoader<TestApplication>("test:blocked"); |
540 CreateLoader<TestApplication>("test:wildcard2"); | 36 CreateLoader<TestApplication>("test:wildcard2"); |
541 CreateLoader<TestApplication>("test:wildcard3"); | 37 CreateLoader<TestApplication>("test:wildcard3"); |
542 RunTest(); | 38 RunWildcardTest(); |
543 } | 39 } |
544 | 40 |
545 TEST_F(CapabilityFilter_WildcardsTest, ContentHandler) { | 41 } // namespace test |
546 RunContentHandlerTest(); | |
547 } | |
548 | |
549 } // namespace | |
550 } // namespace shell | 42 } // namespace shell |
551 } // namespace mojo | 43 } // namespace mojo |
OLD | NEW |