Chromium Code Reviews| Index: shell/shell_apptest.cc |
| diff --git a/shell/shell_apptest.cc b/shell/shell_apptest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..02e505dec3f0a1a25d64b4b4774fbae4d9d45ba7 |
| --- /dev/null |
| +++ b/shell/shell_apptest.cc |
| @@ -0,0 +1,171 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/base_paths.h" |
| +#include "base/bind.h" |
| +#include "base/files/file_path.h" |
| +#include "base/files/file_util.h" |
| +#include "base/path_service.h" |
| +#include "base/run_loop.h" |
| +#include "base/strings/string_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "mojo/common/data_pipe_utils.h" |
| +#include "mojo/public/cpp/application/application_impl.h" |
| +#include "mojo/public/cpp/application/application_test_base.h" |
| +#include "mojo/public/cpp/system/macros.h" |
| +#include "mojo/services/network/public/interfaces/net_address.mojom.h" |
| +#include "services/http_server/public/http_server.mojom.h" |
| +#include "services/http_server/public/http_server_factory.mojom.h" |
| +#include "services/http_server/public/http_server_util.h" |
| +#include "shell/test/pingable.mojom.h" |
| + |
| +namespace mojo { |
| + |
| +namespace { |
| + |
| +std::string GetURL(uint16_t port, const std::string& path) { |
| + return base::StringPrintf("http://127.0.0.1:%u/%s", port, path.c_str()); |
| +} |
| +} |
| + |
| +class GetHandler : public http_server::HttpHandler { |
| + public: |
| + GetHandler(InterfaceRequest<http_server::HttpHandler> request, uint16_t port) |
| + : binding_(this, request.Pass()), port_(port) { |
| + CHECK(PathService::Get(base::FILE_MODULE, &app_path_)); |
| + app_path_ = app_path_.DirName().Append("pingable_app.mojo"); |
| + CHECK(base::PathExists(app_path_)); |
| + } |
| + ~GetHandler() override {} |
| + |
| + bool WaitForIncomingMethodCall() { |
| + return binding_.WaitForIncomingMethodCall(); |
| + } |
| + |
| + private: |
| + // http_server::HttpHandler: |
| + void HandleRequest( |
| + http_server::HttpRequestPtr request, |
| + const Callback<void(http_server::HttpResponsePtr)>& callback) override { |
| + http_server::HttpResponsePtr response; |
| + if (StartsWithASCII(request->relative_url, "/app", true)) { |
| + // Super inefficient, but meh. |
| + std::string data; |
| + base::ReadFileToString(app_path_, &data); |
| + response = http_server::CreateHttpResponse(200, data); |
| + response->content_type = "application/octet-stream"; |
| + } else if (request->relative_url == "/redirect") { |
| + response = http_server::HttpResponse::New(); |
| + response->status_code = 302; |
| + response->custom_headers.insert("Location", GetURL(port_, "app")); |
| + } else { |
| + NOTREACHED(); |
| + } |
| + |
| + callback.Run(response.Pass()); |
| + } |
| + |
| + Binding<http_server::HttpHandler> binding_; |
| + base::FilePath app_path_; |
| + uint16_t port_; |
| + |
| + MOJO_DISALLOW_COPY_AND_ASSIGN(GetHandler); |
| +}; |
| + |
| +class ShellAppTest : public test::ApplicationTestBase { |
| + public: |
| + ShellAppTest() : ApplicationTestBase() {} |
| + ~ShellAppTest() override {} |
| + |
| + protected: |
| + // ApplicationTestBase: |
| + void SetUp() override { |
| + ApplicationTestBase::SetUp(); |
| + |
| + application_impl()->ConnectToService("mojo:http_server", |
| + &http_server_factory_); |
| + |
| + mojo::NetAddressPtr local_address(mojo::NetAddress::New()); |
| + local_address->family = mojo::NET_ADDRESS_FAMILY_IPV4; |
| + local_address->ipv4 = mojo::NetAddressIPv4::New(); |
| + local_address->ipv4->addr.resize(4); |
| + local_address->ipv4->addr[0] = 127; |
| + local_address->ipv4->addr[1] = 0; |
| + local_address->ipv4->addr[2] = 0; |
| + local_address->ipv4->addr[3] = 1; |
| + local_address->ipv4->port = 0; |
| + http_server_factory_->CreateHttpServer(GetProxy(&http_server_), |
| + local_address.Pass()); |
| + |
| + http_server_->GetPort([this](uint16_t p) { port_ = p; }); |
| + EXPECT_TRUE(http_server_.WaitForIncomingMethodCall()); |
| + |
| + InterfacePtr<http_server::HttpHandler> http_handler; |
| + handler_.reset(new GetHandler(GetProxy(&http_handler).Pass(), port_)); |
| + http_server_->SetHandler(".*", http_handler.Pass(), |
| + [](bool result) { EXPECT_TRUE(result); }); |
| + EXPECT_TRUE(http_server_.WaitForIncomingMethodCall()); |
| + } |
| + |
| + std::string GetURL(const std::string& path) { |
| + return ::mojo::GetURL(port_, path); |
| + } |
| + |
| + http_server::HttpServerFactoryPtr http_server_factory_; |
| + http_server::HttpServerPtr http_server_; |
| + scoped_ptr<GetHandler> handler_; |
| + uint16_t port_; |
| + |
| + private: |
| + MOJO_DISALLOW_COPY_AND_ASSIGN(ShellAppTest); |
| +}; |
| + |
| +// Test that we can load apps over http. |
| +TEST_F(ShellAppTest, Http) { |
| + InterfacePtr<Pingable> pingable; |
| + application_impl()->ConnectToService(GetURL("app"), &pingable); |
| + pingable->Ping("hello", [](const String& app_url, const String& message) { |
| + EXPECT_EQ("hello", message); |
| + base::MessageLoop::current()->Quit(); |
| + }); |
| + base::RunLoop().Run(); |
| +} |
| + |
| +// Test that redirects work. |
| +// TODO(aa): Test that apps receive the correct URL parameters. |
| +// TODO(aa): This test runs and passes, except it crashes with a scary-looking |
| +// segfault+smashed stack. I suspect something in HttpServer having to do with |
|
qsr
2015/02/27 15:01:41
Collin is using the http server with headers and d
|
| +// using headers. |
| +TEST_F(ShellAppTest, DISABLED_Redirect) { |
| + InterfacePtr<Pingable> pingable; |
| + application_impl()->ConnectToService(GetURL("redirect"), &pingable); |
| + pingable->Ping("hello", [](const String& app_url, const String& message) { |
| + EXPECT_EQ("hello", message); |
| + base::MessageLoop::current()->Quit(); |
| + }); |
| + base::RunLoop().Run(); |
| +} |
| + |
| +// Test that querystring is not considered when resolving http applications. |
| +TEST_F(ShellAppTest, QueryHandling) { |
| + InterfacePtr<Pingable> pingable1; |
| + InterfacePtr<Pingable> pingable2; |
| + application_impl()->ConnectToService(GetURL("app?foo"), &pingable1); |
| + application_impl()->ConnectToService(GetURL("app?bar"), &pingable2); |
| + |
| + int num_responses = 0; |
| + auto callback = |
| + [this, &num_responses](const String& app_url, const String& message) { |
| + EXPECT_EQ(GetURL("app"), app_url); |
| + EXPECT_EQ("hello", message); |
| + if (++num_responses == 2) { |
| + base::MessageLoop::current()->Quit(); |
| + } |
| + }; |
| + pingable1->Ping("hello", callback); |
| + pingable2->Ping("hello", callback); |
| + base::RunLoop().Run(); |
| +} |
| + |
| +} // namespace mojo |