| Index: mojo/shell/capability_filter_unittest.cc
|
| diff --git a/mojo/shell/capability_filter_unittest.cc b/mojo/shell/capability_filter_unittest.cc
|
| index bdb864573d7cb96399a66550f544bff2a7f2a368..09ceb5fdda486a7db989526f57662c6c9134cbc2 100644
|
| --- a/mojo/shell/capability_filter_unittest.cc
|
| +++ b/mojo/shell/capability_filter_unittest.cc
|
| @@ -2,550 +2,42 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "base/at_exit.h"
|
| -#include "base/bind.h"
|
| -#include "base/macros.h"
|
| -#include "base/memory/scoped_vector.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "mojo/application/public/cpp/application_connection.h"
|
| -#include "mojo/application/public/cpp/application_delegate.h"
|
| -#include "mojo/application/public/cpp/application_impl.h"
|
| -#include "mojo/application/public/cpp/connect.h"
|
| -#include "mojo/application/public/cpp/interface_factory.h"
|
| -#include "mojo/application/public/cpp/service_provider_impl.h"
|
| -#include "mojo/application/public/interfaces/content_handler.mojom.h"
|
| -#include "mojo/common/weak_binding_set.h"
|
| -#include "mojo/public/cpp/bindings/strong_binding.h"
|
| -#include "mojo/shell/application_loader.h"
|
| -#include "mojo/shell/application_manager.h"
|
| -#include "mojo/shell/capability_filter_unittest.mojom.h"
|
| +#include "mojo/shell/capability_filter_test.h"
|
| #include "mojo/shell/test_package_manager.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace mojo {
|
| namespace shell {
|
| -namespace {
|
| +namespace test {
|
|
|
| -const char kTestMimeType[] = "test/mime-type";
|
| -
|
| -// Lives on the main thread of the test.
|
| -// Listens for services exposed/blocked and for application connections being
|
| -// closed. Quits |loop| when all expectations are met.
|
| -class ConnectionValidator : public ApplicationLoader,
|
| - public ApplicationDelegate,
|
| - public InterfaceFactory<Validator>,
|
| - public Validator {
|
| - public:
|
| - ConnectionValidator(const std::set<std::string>& expectations,
|
| - base::MessageLoop* loop)
|
| - : app_(nullptr),
|
| - expectations_(expectations),
|
| - loop_(loop) {}
|
| - ~ConnectionValidator() override {}
|
| -
|
| - bool expectations_met() {
|
| - return unexpected_.empty() && expectations_.empty();
|
| - }
|
| -
|
| - void PrintUnmetExpectations() {
|
| - for (auto expectation : expectations_)
|
| - ADD_FAILURE() << "Unmet: " << expectation;
|
| - for (auto unexpected : unexpected_)
|
| - ADD_FAILURE() << "Unexpected: " << unexpected;
|
| - }
|
| -
|
| - private:
|
| - // Overridden from ApplicationLoader:
|
| - void Load(const GURL& url, InterfaceRequest<Application> request) override {
|
| - app_.reset(new ApplicationImpl(this, request.Pass()));
|
| - }
|
| -
|
| - // Overridden from ApplicationDelegate:
|
| - bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
|
| - connection->AddService<Validator>(this);
|
| - return true;
|
| - }
|
| -
|
| - // Overridden from InterfaceFactory<Validator>:
|
| - void Create(ApplicationConnection* connection,
|
| - InterfaceRequest<Validator> request) override {
|
| - validator_bindings_.AddBinding(this, request.Pass());
|
| - }
|
| -
|
| - // Overridden from Validator:
|
| - void AddServiceCalled(const String& app_url,
|
| - const String& service_url,
|
| - const String& name,
|
| - bool blocked) override {
|
| - Validate(base::StringPrintf("%s %s %s %s",
|
| - blocked ? "B" : "E", app_url.data(), service_url.data(), name.data()));
|
| - }
|
| - void ConnectionClosed(const String& app_url,
|
| - const String& service_url) override {
|
| - Validate(base::StringPrintf("C %s %s", app_url.data(), service_url.data()));
|
| - }
|
| -
|
| - void Validate(const std::string& result) {
|
| - DVLOG(1) << "Validate: " << result;
|
| - auto i = expectations_.find(result);
|
| - if (i != expectations_.end()) {
|
| - expectations_.erase(i);
|
| - if (expectations_.empty())
|
| - loop_->Quit();
|
| - } else {
|
| - // This is a test failure, and will result in PrintUnexpectedExpecations()
|
| - // being called.
|
| - unexpected_.insert(result);
|
| - loop_->Quit();
|
| - }
|
| - }
|
| -
|
| - scoped_ptr<ApplicationImpl> app_;
|
| - std::set<std::string> expectations_;
|
| - std::set<std::string> unexpected_;
|
| - base::MessageLoop* loop_;
|
| - WeakBindingSet<Validator> validator_bindings_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ConnectionValidator);
|
| -};
|
| -
|
| -// This class models an application who will use the shell to interact with a
|
| -// system service. The shell may limit this application's visibility of the full
|
| -// set of interfaces exposed by that service.
|
| -class TestApplication : public ApplicationDelegate {
|
| - public:
|
| - TestApplication() : app_(nullptr) {}
|
| - ~TestApplication() override {}
|
| -
|
| - private:
|
| - // Overridden from ApplicationDelegate:
|
| - void Initialize(ApplicationImpl* app) override {
|
| - app_ = app;
|
| - }
|
| - bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
|
| - // TestApplications receive their Validator via the inbound connection.
|
| - connection->ConnectToService(&validator_);
|
| -
|
| - URLRequestPtr request(URLRequest::New());
|
| - request->url = String::From("test:service");
|
| - connection1_ = app_->ConnectToApplication(request.Pass());
|
| - connection1_->SetRemoteServiceProviderConnectionErrorHandler(
|
| - base::Bind(&TestApplication::ConnectionClosed,
|
| - base::Unretained(this), "test:service"));
|
| -
|
| - URLRequestPtr request2(URLRequest::New());
|
| - request2->url = String::From("test:service2");
|
| - connection2_ = app_->ConnectToApplication(request2.Pass());
|
| - connection2_->SetRemoteServiceProviderConnectionErrorHandler(
|
| - base::Bind(&TestApplication::ConnectionClosed,
|
| - base::Unretained(this), "test:service2"));
|
| - return true;
|
| - }
|
| -
|
| - void ConnectionClosed(const std::string& service_url) {
|
| - validator_->ConnectionClosed(app_->url(), service_url);
|
| - }
|
| -
|
| - ApplicationImpl* app_;
|
| - ValidatorPtr validator_;
|
| - scoped_ptr<ApplicationConnection> connection1_;
|
| - scoped_ptr<ApplicationConnection> connection2_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestApplication);
|
| -};
|
| -
|
| -class TestContentHandler : public ApplicationDelegate,
|
| - public InterfaceFactory<ContentHandler>,
|
| - public ContentHandler {
|
| - public:
|
| - TestContentHandler() : app_(nullptr) {}
|
| - ~TestContentHandler() override {}
|
| -
|
| - private:
|
| - // Overridden from ApplicationDelegate:
|
| - void Initialize(ApplicationImpl* app) override {
|
| - app_ = app;
|
| - }
|
| - bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
|
| - connection->AddService<ContentHandler>(this);
|
| - return true;
|
| - }
|
| -
|
| - // Overridden from InterfaceFactory<ContentHandler>:
|
| - void Create(ApplicationConnection* connection,
|
| - InterfaceRequest<ContentHandler> request) override {
|
| - bindings_.AddBinding(this, request.Pass());
|
| - }
|
| -
|
| - // Overridden from ContentHandler:
|
| - void StartApplication(InterfaceRequest<Application> application,
|
| - URLResponsePtr response) override {
|
| - scoped_ptr<ApplicationDelegate> delegate(new TestApplication);
|
| - embedded_apps_.push_back(
|
| - new ApplicationImpl(delegate.get(), application.Pass()));
|
| - embedded_app_delegates_.push_back(delegate.Pass());
|
| - }
|
| -
|
| - ApplicationImpl* app_;
|
| - WeakBindingSet<ContentHandler> bindings_;
|
| - ScopedVector<ApplicationDelegate> embedded_app_delegates_;
|
| - ScopedVector<ApplicationImpl> embedded_apps_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestContentHandler);
|
| -};
|
| -
|
| -// This class models a system service that exposes two interfaces, Safe and
|
| -// Unsafe. The interface Unsafe is not to be exposed to untrusted applications.
|
| -class ServiceApplication : public ApplicationDelegate,
|
| - public InterfaceFactory<Safe>,
|
| - public InterfaceFactory<Unsafe>,
|
| - public Safe,
|
| - public Unsafe {
|
| - public:
|
| - ServiceApplication() : app_(nullptr) {}
|
| - ~ServiceApplication() override {}
|
| -
|
| - private:
|
| - // Overridden from ApplicationDelegate:
|
| - void Initialize(ApplicationImpl* app) override {
|
| - app_ = app;
|
| - // ServiceApplications have no capability filter and can thus connect
|
| - // directly to the validator application.
|
| - URLRequestPtr request(URLRequest::New());
|
| - request->url = String::From("test:validator");
|
| - app_->ConnectToService(request.Pass(), &validator_);
|
| - }
|
| - bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
|
| - AddService<Safe>(connection);
|
| - AddService<Unsafe>(connection);
|
| - return true;
|
| - }
|
| -
|
| - // Overridden from InterfaceFactory<Safe>:
|
| - void Create(ApplicationConnection* connection,
|
| - InterfaceRequest<Safe> request) override {
|
| - safe_bindings_.AddBinding(this, request.Pass());
|
| - }
|
| -
|
| - // Overridden from InterfaceFactory<Unsafe>:
|
| - void Create(ApplicationConnection* connection,
|
| - InterfaceRequest<Unsafe> request) override {
|
| - unsafe_bindings_.AddBinding(this, request.Pass());
|
| - }
|
| -
|
| - template <typename Interface>
|
| - void AddService(ApplicationConnection* connection) {
|
| - validator_->AddServiceCalled(connection->GetRemoteApplicationURL(),
|
| - connection->GetConnectionURL(),
|
| - Interface::Name_,
|
| - !connection->AddService<Interface>(this));
|
| - }
|
| -
|
| - ApplicationImpl* app_;
|
| - ValidatorPtr validator_;
|
| - WeakBindingSet<Safe> safe_bindings_;
|
| - WeakBindingSet<Unsafe> unsafe_bindings_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ServiceApplication);
|
| -};
|
| -
|
| -// A custom Fetcher used to trigger a content handler for kTestMimeType for a
|
| -// specific test.
|
| -class TestFetcher : public Fetcher {
|
| - public:
|
| - TestFetcher(const GURL& url, const FetchCallback& callback)
|
| - : Fetcher(callback),
|
| - url_(url) {
|
| - loader_callback_.Run(make_scoped_ptr(this));
|
| - }
|
| - ~TestFetcher() override {}
|
| -
|
| - private:
|
| - // Overridden from Fetcher:
|
| - const GURL& GetURL() const override { return url_; }
|
| - GURL GetRedirectURL() const override { return GURL(); }
|
| - GURL GetRedirectReferer() const override { return GURL(); }
|
| - URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
|
| - uint32_t skip) override {
|
| - URLResponsePtr response(URLResponse::New());
|
| - response->url = url_.spec();
|
| - return response.Pass();
|
| - }
|
| - void AsPath(
|
| - base::TaskRunner* task_runner,
|
| - base::Callback<void(const base::FilePath&, bool)> callback) override {}
|
| - std::string MimeType() override { return kTestMimeType; }
|
| - bool HasMojoMagic() override { return false; }
|
| - bool PeekFirstLine(std::string* line) override { return false; }
|
| -
|
| - const GURL url_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestFetcher);
|
| -};
|
| -
|
| -class CFTestPackageManager : public TestPackageManager {
|
| - public:
|
| - CFTestPackageManager() {}
|
| - ~CFTestPackageManager() override {}
|
| -
|
| - void set_use_test_fetcher(bool use_test_fetcher) {
|
| - use_test_fetcher_ = use_test_fetcher;
|
| - }
|
| -
|
| - private:
|
| - // Overridden from TestPackageManager:
|
| - void FetchRequest(URLRequestPtr request,
|
| - const Fetcher::FetchCallback& loader_callback) override {
|
| - if (use_test_fetcher_)
|
| - new TestFetcher(GURL(request->url), loader_callback);
|
| - }
|
| -
|
| - bool use_test_fetcher_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CFTestPackageManager);
|
| -};
|
| -
|
| -class TestLoader : public ApplicationLoader {
|
| - public:
|
| - explicit TestLoader(ApplicationDelegate* delegate) : delegate_(delegate) {}
|
| - ~TestLoader() override {}
|
| -
|
| - private:
|
| - // Overridden from ApplicationLoader:
|
| - void Load(const GURL& url, InterfaceRequest<Application> request) override {
|
| - app_.reset(new ApplicationImpl(delegate_.get(), request.Pass()));
|
| - }
|
| -
|
| - scoped_ptr<ApplicationDelegate> delegate_;
|
| - scoped_ptr<ApplicationImpl> app_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestLoader);
|
| -};
|
| -
|
| -class CapabilityFilterTest : public testing::Test {
|
| - public:
|
| - CapabilityFilterTest()
|
| - : test_package_manager_(nullptr),
|
| - validator_(nullptr) {}
|
| - ~CapabilityFilterTest() override {}
|
| -
|
| - protected:
|
| - void RunApplication(const std::string& url, const CapabilityFilter& filter) {
|
| - ServiceProviderPtr services;
|
| -
|
| - // We expose Validator to the test application via ConnectToApplication
|
| - // because we don't allow the test application to connect to test:validator.
|
| - // Adding it to the CapabilityFilter would interfere with the test.
|
| - ServiceProviderPtr exposed_services;
|
| - (new ServiceProviderImpl(GetProxy(&exposed_services)))->
|
| - AddService<Validator>(validator_);
|
| - scoped_ptr<ConnectToApplicationParams> params(
|
| - new ConnectToApplicationParams);
|
| - params->SetTarget(Identity(GURL(url), std::string(), filter));
|
| - params->set_services(GetProxy(&services));
|
| - params->set_exposed_services(exposed_services.Pass());
|
| - params->set_on_application_end(base::MessageLoop::QuitWhenIdleClosure());
|
| - application_manager_->ConnectToApplication(params.Pass());
|
| - }
|
| -
|
| - void InitValidator(const std::set<std::string>& expectations) {
|
| - validator_ = new ConnectionValidator(expectations, &loop_);
|
| - application_manager()->SetLoaderForURL(make_scoped_ptr(validator_),
|
| - GURL("test:validator"));
|
| - }
|
| -
|
| - template <class T>
|
| - void CreateLoader(const std::string& url) {
|
| - application_manager_->SetLoaderForURL(
|
| - make_scoped_ptr(new TestLoader(new T)), GURL(url));
|
| - }
|
| -
|
| - virtual void RunTest() {
|
| - loop()->Run();
|
| - EXPECT_TRUE(validator_->expectations_met());
|
| - if (!validator_->expectations_met())
|
| - validator_->PrintUnmetExpectations();
|
| - }
|
| -
|
| - void RunContentHandlerTest() {
|
| - set_use_test_fetcher();
|
| -
|
| - GURL content_handler_url("test:content_handler");
|
| - test_package_manager_->RegisterContentHandler(kTestMimeType,
|
| - content_handler_url);
|
| -
|
| - CreateLoader<TestContentHandler>(content_handler_url.spec());
|
| - RunTest();
|
| - }
|
| -
|
| - base::MessageLoop* loop() { return &loop_; }
|
| - ApplicationManager* application_manager() {
|
| - return application_manager_.get();
|
| - }
|
| - ConnectionValidator* validator() { return validator_; }
|
| - void set_use_test_fetcher() {
|
| - test_package_manager_->set_use_test_fetcher(true);
|
| - }
|
| -
|
| - // Overridden from testing::Test:
|
| - void SetUp() override {
|
| - test_package_manager_ = new CFTestPackageManager;
|
| - application_manager_.reset(
|
| - new ApplicationManager(make_scoped_ptr(test_package_manager_)));
|
| - CreateLoader<ServiceApplication>("test:service");
|
| - CreateLoader<ServiceApplication>("test:service2");
|
| - }
|
| - void TearDown() override {
|
| - test_package_manager_->set_use_test_fetcher(false);
|
| - application_manager_.reset();
|
| - }
|
| -
|
| - private:
|
| - template<class T>
|
| - scoped_ptr<ApplicationDelegate> CreateApplicationDelegate() {
|
| - return scoped_ptr<ApplicationDelegate>(new T);
|
| - }
|
| -
|
| - CFTestPackageManager* test_package_manager_;
|
| - base::ShadowingAtExitManager at_exit_;
|
| - base::MessageLoop loop_;
|
| - scoped_ptr<ApplicationManager> application_manager_;
|
| - ConnectionValidator* validator_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CapabilityFilterTest);
|
| -};
|
| -
|
| -class CapabilityFilter_BlockingTest : public CapabilityFilterTest {
|
| +class CapabilityFilterApplicationTest : public CapabilityFilterTest {
|
| public:
|
| - CapabilityFilter_BlockingTest() {}
|
| - ~CapabilityFilter_BlockingTest() override {}
|
| -
|
| - protected:
|
| - void RunTest() override {
|
| - // This first application can only connect to test:service. Connections to
|
| - // test:service2 will be blocked. It also will only be able to see the
|
| - // "Safe" interface exposed by test:service. It will be blocked from seeing
|
| - // "Unsafe".
|
| - AllowedInterfaces interfaces;
|
| - interfaces.insert(Safe::Name_);
|
| - CapabilityFilter filter;
|
| - filter["test:service"] = interfaces;
|
| - RunApplication("test:untrusted", filter);
|
| -
|
| - // This second application can connect to both test:service and
|
| - // test:service2. It can connect to both "Safe" and "Unsafe" interfaces.
|
| - RunApplication("test:trusted", GetPermissiveCapabilityFilter());
|
| -
|
| - CapabilityFilterTest::RunTest();
|
| - }
|
| + CapabilityFilterApplicationTest() {}
|
| + ~CapabilityFilterApplicationTest() override {}
|
|
|
| private:
|
| // Overridden from CapabilityFilterTest:
|
| - void SetUp() override {
|
| - CapabilityFilterTest::SetUp();
|
| -
|
| - std::set<std::string> expectations;
|
| - expectations.insert("E test:trusted test:service mojo::shell::Safe");
|
| - expectations.insert("E test:trusted test:service mojo::shell::Unsafe");
|
| - expectations.insert("E test:trusted test:service2 mojo::shell::Safe");
|
| - expectations.insert("E test:trusted test:service2 mojo::shell::Unsafe");
|
| - expectations.insert("E test:untrusted test:service mojo::shell::Safe");
|
| - expectations.insert("B test:untrusted test:service mojo::shell::Unsafe");
|
| - expectations.insert("C test:untrusted test:service2");
|
| - InitValidator(expectations);
|
| + PackageManager* CreatePackageManager() override {
|
| + return new TestPackageManager;
|
| }
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(CapabilityFilter_BlockingTest);
|
| + DISALLOW_COPY_AND_ASSIGN(CapabilityFilterApplicationTest);
|
| };
|
|
|
| -TEST_F(CapabilityFilter_BlockingTest, Application) {
|
| +TEST_F(CapabilityFilterApplicationTest, Blocking) {
|
| CreateLoader<TestApplication>("test:trusted");
|
| CreateLoader<TestApplication>("test:untrusted");
|
| - RunTest();
|
| -}
|
| -
|
| -TEST_F(CapabilityFilter_BlockingTest, ContentHandler) {
|
| - RunContentHandlerTest();
|
| + RunBlockingTest();
|
| }
|
|
|
| -class CapabilityFilter_WildcardsTest : public CapabilityFilterTest {
|
| - public:
|
| - CapabilityFilter_WildcardsTest() {}
|
| - ~CapabilityFilter_WildcardsTest() override {}
|
| -
|
| - protected:
|
| - void RunTest() override {
|
| - // This application is allowed to connect to any application because of a
|
| - // wildcard rule, and any interface exposed because of a wildcard rule in
|
| - // the interface array.
|
| - RunApplication("test:wildcard", GetPermissiveCapabilityFilter());
|
| -
|
| - // This application is allowed to connect to no other applications because
|
| - // of an empty capability filter.
|
| - RunApplication("test:blocked", CapabilityFilter());
|
| -
|
| - // This application is allowed to connect to any application because of a
|
| - // wildcard rule but may not connect to any interfaces because of an empty
|
| - // interface array.
|
| - CapabilityFilter filter1;
|
| - filter1["*"] = AllowedInterfaces();
|
| - RunApplication("test:wildcard2", filter1);
|
| -
|
| - // This application is allowed to connect to both test:service and
|
| - // test:service2, and may see any interface exposed by test:service but only
|
| - // the Safe interface exposed by test:service2.
|
| - AllowedInterfaces interfaces2;
|
| - interfaces2.insert("*");
|
| - CapabilityFilter filter2;
|
| - filter2["test:service"] = interfaces2;
|
| - AllowedInterfaces interfaces3;
|
| - interfaces3.insert(Safe::Name_);
|
| - filter2["test:service2"] = interfaces3;
|
| - RunApplication("test:wildcard3", filter2);
|
| -
|
| - CapabilityFilterTest::RunTest();
|
| - }
|
| -
|
| - private:
|
| - // Overridden from CapabilityFilterTest:
|
| - void SetUp() override {
|
| - CapabilityFilterTest::SetUp();
|
| -
|
| - std::set<std::string> expectations;
|
| - expectations.insert("E test:wildcard test:service mojo::shell::Safe");
|
| - expectations.insert("E test:wildcard test:service mojo::shell::Unsafe");
|
| - expectations.insert("E test:wildcard test:service2 mojo::shell::Safe");
|
| - expectations.insert("E test:wildcard test:service2 mojo::shell::Unsafe");
|
| - expectations.insert("C test:blocked test:service");
|
| - expectations.insert("C test:blocked test:service2");
|
| - expectations.insert("B test:wildcard2 test:service mojo::shell::Safe");
|
| - expectations.insert("B test:wildcard2 test:service mojo::shell::Unsafe");
|
| - expectations.insert("B test:wildcard2 test:service2 mojo::shell::Safe");
|
| - expectations.insert("B test:wildcard2 test:service2 mojo::shell::Unsafe");
|
| - expectations.insert("E test:wildcard3 test:service mojo::shell::Safe");
|
| - expectations.insert("E test:wildcard3 test:service mojo::shell::Unsafe");
|
| - expectations.insert("E test:wildcard3 test:service2 mojo::shell::Safe");
|
| - expectations.insert("B test:wildcard3 test:service2 mojo::shell::Unsafe");
|
| - InitValidator(expectations);
|
| - }
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CapabilityFilter_WildcardsTest);
|
| -};
|
| -
|
| -TEST_F(CapabilityFilter_WildcardsTest, Application) {
|
| +TEST_F(CapabilityFilterApplicationTest, Wildcards) {
|
| CreateLoader<TestApplication>("test:wildcard");
|
| CreateLoader<TestApplication>("test:blocked");
|
| CreateLoader<TestApplication>("test:wildcard2");
|
| CreateLoader<TestApplication>("test:wildcard3");
|
| - RunTest();
|
| -}
|
| -
|
| -TEST_F(CapabilityFilter_WildcardsTest, ContentHandler) {
|
| - RunContentHandlerTest();
|
| + RunWildcardTest();
|
| }
|
|
|
| -} // namespace
|
| +} // namespace test
|
| } // namespace shell
|
| } // namespace mojo
|
|
|