Commit 030a2631 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[WebLayer] Add test of behavior when hitting SSL errors

This CL adds a browsertest that a navigation to a URL of type HTTPS
succeeds by default and fails if the site has a mismatched certificate.
We're adding this test now in anticipation of implementing SSL
interstitials, at which point we'll expand the test to test the
interstitial behavior.

This CL also adds necessary infrastructure to enable navigations to URLs
supplied by embedded test servers of type HTTPS:

- A ContentUtilityClient implementation whose registration of network
  binders can be overridden.
- An installation of
  content::NetworkServiceTestHelper::RegisterNetworkBinders() for
  weblayer browsertests.

Note that I first tried a simpler mechanism for the above: Invoking
the relevant parts of the body of
content::NetworkServiceTestHelper::RegisterNetworkBinders() directly
from browsertests_main.cc:main() when in utility processes. However,
this appears to be too early to invoke these functions, as it resulted
in the following:

[223377:223377:1015/171544.292381:ERROR:sandbox_linux.cc(367)] InitializeSandbox() called with multiple threads in process utility. Try waiting for /proc to be updated.
[223377:223377:1015/171544.327809:FATAL:thread_helpers.cc(104)] Current process is not mono-threaded! (iterations: 25)

0 0x7ff318df263f base::debug::CollectStackTrace()
1 0x7ff318b217ed base::debug::StackTrace::StackTrace()
2 0x7ff318b217a8 base::debug::StackTrace::StackTrace()
3 0x7ff318b73559 logging::LogMessage::~LogMessage()
4 0x7ff2f3401232 sandbox::(anonymous namespace)::RunWhileTrue()
5 0x7ff2f3400f71 sandbox::ThreadHelpers::AssertSingleThreaded()
6 0x7ff2f34012d1 sandbox::ThreadHelpers::AssertSingleThreaded()
7 0x7ff3067300e4 service_manager::SandboxLinux::InitializeSandbox()
8 0x7ff30672929b service_manager::Sandbox::Initialize()
9 0x7ff313276abf content::UtilityMain()

Change-Id: I1c89b7b77b028aca06c28d0b83ab1a7dbcf9f117
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1859993
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707350}
parent 8105ee98
......@@ -67,6 +67,8 @@ jumbo_static_library("weblayer_lib") {
"public/navigation_controller.h",
"public/navigation_observer.h",
"public/profile.h",
"utility/content_utility_client_impl.cc",
"utility/content_utility_client_impl.h",
]
configs += [
......@@ -91,6 +93,7 @@ jumbo_static_library("weblayer_lib") {
"//content/public/child",
"//content/public/common",
"//content/public/common:service_names",
"//content/public/utility",
"//net",
"//net:net_resources",
"//sandbox",
......
......@@ -20,6 +20,7 @@
#include "ui/base/ui_base_paths.h"
#include "weblayer/browser/content_browser_client_impl.h"
#include "weblayer/common/content_client_impl.h"
#include "weblayer/utility/content_utility_client_impl.h"
#if defined(OS_ANDROID)
#include "base/android/apk_assets.h"
......@@ -181,4 +182,10 @@ ContentMainDelegateImpl::CreateContentBrowserClient() {
return browser_client_.get();
}
content::ContentUtilityClient*
ContentMainDelegateImpl::CreateContentUtilityClient() {
utility_client_ = std::make_unique<ContentUtilityClientImpl>();
return utility_client_.get();
}
} // namespace weblayer
......@@ -16,6 +16,7 @@
namespace weblayer {
class ContentClientImpl;
class ContentBrowserClientImpl;
class ContentUtilityClientImpl;
class ContentMainDelegateImpl : public content::ContentMainDelegate {
public:
......@@ -29,12 +30,14 @@ class ContentMainDelegateImpl : public content::ContentMainDelegate {
const std::string& process_type,
const content::MainFunctionParams& main_function_params) override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentUtilityClient* CreateContentUtilityClient() override;
private:
void InitializeResourceBundle();
MainParams params_;
std::unique_ptr<ContentBrowserClientImpl> browser_client_;
std::unique_ptr<ContentUtilityClientImpl> utility_client_;
std::unique_ptr<ContentClientImpl> content_client_;
DISALLOW_COPY_AND_ASSIGN(ContentMainDelegateImpl);
......
......@@ -85,6 +85,7 @@ test("weblayer_browsertests") {
sources = [
"browsertests_main.cc",
"ssl_browsertest.cc",
"test_launcher_delegate_impl.cc",
"test_launcher_delegate_impl.h",
"weblayer_browser_test.cc",
......
include_rules = [
"+content/public/common",
"+content/public/test",
"+net/test",
]
......@@ -4,12 +4,33 @@
#include "base/command_line.h"
#include "base/test/launcher/test_launcher.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/network_service_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "weblayer/test/test_launcher_delegate_impl.h"
#include "weblayer/utility/content_utility_client_impl.h"
int main(int argc, char** argv) {
base::CommandLine::Init(argc, argv);
size_t parallel_jobs = base::NumParallelJobs();
// Set up a working test environment for the network service in case it's
// used. Only create this object in the utility process, so that its members
// don't interfere with other test objects in the browser process.
std::unique_ptr<content::NetworkServiceTestHelper>
network_service_test_helper;
if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kProcessType) == switches::kUtilityProcess) {
network_service_test_helper =
std::make_unique<content::NetworkServiceTestHelper>();
weblayer::ContentUtilityClientImpl::
SetNetworkBinderCreationCallbackForTests(base::BindRepeating(
[](content::NetworkServiceTestHelper* helper,
service_manager::BinderRegistry* registry) {
helper->RegisterNetworkBinders(registry);
},
network_service_test_helper.get()));
}
weblayer::TestLauncherDelegateImpl launcher_delegate;
return content::LaunchTests(&launcher_delegate, parallel_jobs, argc, argv);
}
// Copyright 2019 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 "weblayer/test/weblayer_browser_test.h"
#include "base/files/file_path.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "weblayer/test/weblayer_browser_test_utils.h"
namespace weblayer {
IN_PROC_BROWSER_TEST_F(WebLayerBrowserTest, Https) {
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("weblayer/test/data")));
net::EmbeddedTestServer https_server_mismatched(
net::EmbeddedTestServer::TYPE_HTTPS);
https_server_mismatched.SetSSLConfig(
net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
https_server_mismatched.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("weblayer/test/data")));
ASSERT_TRUE(https_server.Start());
ASSERT_TRUE(https_server_mismatched.Start());
// First navigate to an OK page.
GURL initial_url = https_server.GetURL("/simple_page.html");
ASSERT_EQ("127.0.0.1", initial_url.host());
NavigateAndWaitForCompletion(initial_url, shell());
// Now do a navigation that should result in an SSL error.
GURL url_with_mismatched_cert =
https_server_mismatched.GetURL("/simple_page.html");
NavigateAndWaitForFailure(url_with_mismatched_cert, shell());
// TODO(blundell): Adapt the testing of the interstitial appearing from
// //chrome's ssl_browsertest.cc:(1462-1465) once the interstitial
// functionality is brought up.
}
} // namespace weblayer
......@@ -13,7 +13,7 @@ IN_PROC_BROWSER_TEST_F(WebLayerBrowserTest, Basic) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/simple_page.html");
NavigateAndWait(url, shell());
NavigateAndWaitForCompletion(url, shell());
}
} // namespace weblayer
......@@ -19,11 +19,15 @@ namespace {
// Runs |closure| once |url| is successfully navigated to.
class TestNavigationObserver : public NavigationObserver {
public:
enum class NavigationEventToObserve { Completion, Failure };
TestNavigationObserver(base::OnceClosure closure,
const GURL& url,
NavigationEventToObserve event,
Shell* shell)
: closure_(std::move(closure)),
url_(url),
event_(event),
browser_(shell->browser_controller()) {
browser_->GetNavigationController()->AddObserver(this);
}
......@@ -35,23 +39,47 @@ class TestNavigationObserver : public NavigationObserver {
private:
// NavigationObserver implementation:
void NavigationCompleted(Navigation* navigation) override {
if (navigation->GetURL() == url_)
if (navigation->GetURL() == url_ &&
event_ == NavigationEventToObserve::Completion)
std::move(closure_).Run();
}
void NavigationFailed(Navigation* navigation) override {
if (navigation->GetURL() == url_ &&
event_ == NavigationEventToObserve::Failure) {
std::move(closure_).Run();
}
}
base::OnceClosure closure_;
const GURL url_;
NavigationEventToObserve event_;
BrowserController* browser_;
};
} // namespace
void NavigateAndWait(const GURL& url, Shell* shell) {
// Navigates to |url| in |shell| and waits for |event| to occur.
void NavigateAndWaitForEvent(
const GURL& url,
Shell* shell,
TestNavigationObserver::NavigationEventToObserve event) {
base::RunLoop run_loop;
TestNavigationObserver test_observer(run_loop.QuitClosure(), url, shell);
TestNavigationObserver test_observer(run_loop.QuitClosure(), url, event,
shell);
shell->browser_controller()->GetNavigationController()->Navigate(url);
run_loop.Run();
}
} // namespace
void NavigateAndWaitForCompletion(const GURL& url, Shell* shell) {
NavigateAndWaitForEvent(
url, shell, TestNavigationObserver::NavigationEventToObserve::Completion);
}
void NavigateAndWaitForFailure(const GURL& url, Shell* shell) {
NavigateAndWaitForEvent(
url, shell, TestNavigationObserver::NavigationEventToObserve::Failure);
}
} // namespace weblayer
......@@ -10,8 +10,11 @@ class GURL;
namespace weblayer {
class Shell;
// Navigates |shell| to |url| and wait for successful navigation.
void NavigateAndWait(const GURL& url, Shell* shell);
// Navigates |shell| to |url| and wait for completed navigation.
void NavigateAndWaitForCompletion(const GURL& url, Shell* shell);
// Navigates |shell| to |url| and wait for failed navigation.
void NavigateAndWaitForFailure(const GURL& url, Shell* shell);
} // namespace weblayer
......
include_rules = [
"+content/public/utility",
]
// Copyright 2019 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 "weblayer/utility/content_utility_client_impl.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/no_destructor.h"
namespace weblayer {
namespace {
base::LazyInstance<ContentUtilityClientImpl::NetworkBinderCreationCallback>::
Leaky g_network_binder_creation_callback = LAZY_INSTANCE_INITIALIZER;
} // namespace
// static
void ContentUtilityClientImpl::SetNetworkBinderCreationCallbackForTests(
NetworkBinderCreationCallback callback) {
g_network_binder_creation_callback.Get() = std::move(callback);
}
ContentUtilityClientImpl::ContentUtilityClientImpl() {}
ContentUtilityClientImpl::~ContentUtilityClientImpl() = default;
void ContentUtilityClientImpl::RegisterNetworkBinders(
service_manager::BinderRegistry* registry) {
if (g_network_binder_creation_callback.Get())
g_network_binder_creation_callback.Get().Run(registry);
}
} // namespace weblayer
// Copyright 2019 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.
#ifndef WEBLAYER_UTILITY_CONTENT_UTILITY_CLIENT_IMPL_H_
#define WEBLAYER_UTILITY_CONTENT_UTILITY_CLIENT_IMPL_H_
#include <string>
#include "base/callback.h"
#include "content/public/utility/content_utility_client.h"
namespace weblayer {
class ContentUtilityClientImpl : public content::ContentUtilityClient {
public:
using NetworkBinderCreationCallback =
base::RepeatingCallback<void(service_manager::BinderRegistry*)>;
static void SetNetworkBinderCreationCallbackForTests(
NetworkBinderCreationCallback callback);
ContentUtilityClientImpl();
~ContentUtilityClientImpl() override;
// content::ContentUtilityClient:
void RegisterNetworkBinders(
service_manager::BinderRegistry* registry) override;
private:
DISALLOW_COPY_AND_ASSIGN(ContentUtilityClientImpl);
};
} // namespace weblayer
#endif // WEBLAYER_UTILITY_CONTENT_UTILITY_CLIENT_IMPL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment