Chromium Code Reviews| Index: chrome/browser/io_thread_unittest.cc | 
| diff --git a/chrome/browser/io_thread_unittest.cc b/chrome/browser/io_thread_unittest.cc | 
| index 443030626ad364113449b27903c8de0c86766bc2..2fc176be3429f8fd5898a1b7c588e6ee53447b32 100644 | 
| --- a/chrome/browser/io_thread_unittest.cc | 
| +++ b/chrome/browser/io_thread_unittest.cc | 
| @@ -4,22 +4,80 @@ | 
| #include "base/command_line.h" | 
| #include "base/metrics/field_trial.h" | 
| +#include "base/prefs/pref_registry_simple.h" | 
| +#include "base/prefs/pref_service.h" | 
| +#include "base/prefs/testing_pref_service.h" | 
| #include "base/test/mock_entropy_provider.h" | 
| +#include "chrome/browser/extensions/event_router_forwarder.h" | 
| #include "chrome/browser/io_thread.h" | 
| #include "chrome/common/chrome_switches.h" | 
| +#include "chrome/common/pref_names.h" | 
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" | 
| +#include "components/policy/core/common/mock_policy_service.h" | 
| +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" | 
| +#include "components/proxy_config/proxy_config_pref_names.h" | 
| +#include "content/public/test/test_browser_thread_bundle.h" | 
| +#include "net/http/http_auth_handler_negotiate.h" | 
| #include "net/http/http_network_session.h" | 
| #include "net/http/http_server_properties_impl.h" | 
| #include "net/quic/quic_protocol.h" | 
| #include "testing/gmock/include/gmock/gmock.h" | 
| #include "testing/gtest/include/gtest/gtest.h" | 
| +#if defined(OS_CHROMEOS) | 
| +#include "chromeos/dbus/dbus_thread_manager.h" | 
| +#include "chromeos/network/network_handler.h" | 
| +#endif | 
| + | 
| + | 
| namespace test { | 
| using ::testing::ElementsAre; | 
| +using ::testing::ReturnRef; | 
| +// Class used for accessing IOThread methods (friend of IOThread). Creating | 
| +// an IOThreadPeer creates and initializes an IOThread instance set up for | 
| +// testing, deleting it cleanly closes down and deletes the IOThread instance. | 
| class IOThreadPeer { | 
| 
 
asanka
2015/11/04 16:05:44
Shall we maintain IOThreadPeer as a pure peer? It
 
aberent
2015/11/06 13:57:34
Done.
 
 | 
| public: | 
| + IOThreadPeer() { | 
| +#if defined(ENABLE_EXTENSIONS) | 
| + event_router_forwarder_ = new extensions::EventRouterForwarder; | 
| +#endif | 
| + PrefRegistrySimple* pref_registry = pref_service_.registry(); | 
| + IOThread::RegisterPrefs(pref_registry); | 
| + PrefProxyConfigTrackerImpl::RegisterPrefs(pref_registry); | 
| + ssl_config::SSLConfigServiceManager::RegisterPrefs(pref_registry); | 
| + | 
| + // Set up default function behaviour. | 
| + EXPECT_CALL(policy_service_, | 
| + GetPolicies(policy::PolicyNamespace( | 
| + policy::POLICY_DOMAIN_CHROME, std::string()))) | 
| + .WillRepeatedly(ReturnRef(policy_map_)); | 
| + | 
| +#if defined(OS_CHROMEOS) | 
| + // Needed by IOThread constructor. | 
| + chromeos::DBusThreadManager::Initialize(); | 
| + chromeos::NetworkHandler::Initialize(); | 
| +#endif | 
| + io_thread_.reset(new IOThread(&pref_service_, &policy_service_, nullptr, | 
| + event_router_forwarder_.get())); | 
| + // Sadly the test can't call IOThread::Init here, since on Mac the IOThread | 
| + // constructor has to run on the UI thread, and will DCHECK if it doesn't; | 
| + // but on all platforms IOThread::Init will DCHECK if it isn't on the IO | 
| + // Thread. | 
| + io_thread_->SetGlobalsForTesting(&globals_); | 
| + io_thread_->CreateDefaultAuthHandlerFactory(); | 
| + } | 
| + | 
| + ~IOThreadPeer() { | 
| + io_thread_->SetGlobalsForTesting(nullptr); | 
| +#if defined(OS_CHROMEOS) | 
| + chromeos::NetworkHandler::Shutdown(); | 
| + chromeos::DBusThreadManager::Shutdown(); | 
| +#endif | 
| + } | 
| + | 
| static void ConfigureQuicGlobals( | 
| const base::CommandLine& command_line, | 
| base::StringPiece quic_trial_group, | 
| @@ -45,6 +103,21 @@ class IOThreadPeer { | 
| net::HttpNetworkSession::Params* params) { | 
| IOThread::InitializeNetworkSessionParamsFromGlobals(globals, params); | 
| } | 
| + | 
| + IOThread* io_thread() { return io_thread_.get(); } | 
| + | 
| + TestingPrefServiceSimple* pref_service() { return &pref_service_; } | 
| + | 
| + private: | 
| + content::TestBrowserThreadBundle thread_bundle_; | 
| + TestingPrefServiceSimple pref_service_; | 
| + scoped_refptr<extensions::EventRouterForwarder> event_router_forwarder_; | 
| + policy::PolicyMap policy_map_; | 
| + policy::MockPolicyService policy_service_; | 
| + scoped_ptr<IOThread> io_thread_; | 
| + IOThread::Globals globals_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(IOThreadPeer); | 
| }; | 
| class IOThreadTest : public testing::Test { | 
| @@ -498,4 +571,98 @@ TEST_F(IOThreadTest, QuicDisallowedByPolicy) { | 
| EXPECT_FALSE(params.enable_quic); | 
| } | 
| +TEST_F(IOThreadTest, UpdateNegotiateDisableCnameLookup) { | 
| + IOThreadPeer peer; | 
| 
 
asanka
2015/11/04 16:05:44
Exercising the thread restrictions is important gi
 
aberent
2015/11/06 13:57:34
Done.
 
 | 
| + | 
| + auto factory = static_cast<net::HttpAuthHandlerRegistryFactory*>( | 
| + peer.io_thread()->globals()->http_auth_handler_factory.get()); | 
| + | 
| + auto negotiate_factory = static_cast<net::HttpAuthHandlerNegotiate::Factory*>( | 
| + factory->GetSchemeFactory(net::kNegotiateAuthScheme)); | 
| + // If we don't have a negotiate factory (net wasn't built with Kerberos) the | 
| + // policy does nothing so we can't test anything. | 
| + if (!negotiate_factory) | 
| + return; | 
| + | 
| + peer.pref_service()->SetBoolean(prefs::kDisableAuthNegotiateCnameLookup, | 
| + false); | 
| + EXPECT_FALSE(negotiate_factory->disable_cname_lookup()); | 
| + peer.pref_service()->SetBoolean(prefs::kDisableAuthNegotiateCnameLookup, | 
| + true); | 
| + EXPECT_TRUE(negotiate_factory->disable_cname_lookup()); | 
| +} | 
| + | 
| +TEST_F(IOThreadTest, UpdateEnableAuthNegotiatePort) { | 
| + IOThreadPeer peer; | 
| + | 
| + auto factory = static_cast<net::HttpAuthHandlerRegistryFactory*>( | 
| + peer.io_thread()->globals()->http_auth_handler_factory.get()); | 
| + | 
| + auto negotiate_factory = static_cast<net::HttpAuthHandlerNegotiate::Factory*>( | 
| + factory->GetSchemeFactory(net::kNegotiateAuthScheme)); | 
| + // If we don't have a negotiate factory (net wasn't built with Kerberos) the | 
| + // policy does nothing so we can't test anything. | 
| + if (!negotiate_factory) | 
| + return; | 
| + | 
| + peer.pref_service()->SetBoolean(prefs::kEnableAuthNegotiatePort, false); | 
| + EXPECT_FALSE(negotiate_factory->use_port()); | 
| + peer.pref_service()->SetBoolean(prefs::kEnableAuthNegotiatePort, true); | 
| + EXPECT_TRUE(negotiate_factory->use_port()); | 
| +} | 
| + | 
| +TEST_F(IOThreadTest, UpdateServerWhitelist) { | 
| + IOThreadPeer peer; | 
| + | 
| + GURL url("http://test.example.com"); | 
| + | 
| + peer.pref_service()->SetString(prefs::kAuthServerWhitelist, ""); | 
| + net::URLSecurityManager* security_manager = | 
| + peer.io_thread()->globals()->url_security_manager.get(); | 
| + EXPECT_FALSE(security_manager->CanUseDefaultCredentials(url)); | 
| + | 
| + peer.pref_service()->SetString(prefs::kAuthServerWhitelist, "*"); | 
| + security_manager = peer.io_thread()->globals()->url_security_manager.get(); | 
| + EXPECT_TRUE(security_manager->CanUseDefaultCredentials(url)); | 
| +} | 
| + | 
| +TEST_F(IOThreadTest, UpdateDelegateWhitelist) { | 
| + IOThreadPeer peer; | 
| + | 
| + GURL url("http://test.example.com"); | 
| + | 
| + peer.pref_service()->SetString(prefs::kAuthNegotiateDelegateWhitelist, ""); | 
| + net::URLSecurityManager* security_manager = | 
| + peer.io_thread()->globals()->url_security_manager.get(); | 
| + EXPECT_FALSE(security_manager->CanDelegate(url)); | 
| + | 
| + peer.pref_service()->SetString(prefs::kAuthNegotiateDelegateWhitelist, "*"); | 
| + security_manager = peer.io_thread()->globals()->url_security_manager.get(); | 
| + EXPECT_TRUE(security_manager->CanDelegate(url)); | 
| +} | 
| + | 
| +#if defined(OS_ANDROID) | 
| +// AuthAndroidNegotiateAccountType is only used on Android. | 
| +TEST_F(IOThreadTest, UpdateAuthAndroidNegotiateAccountType) { | 
| + IOThreadPeer peer; | 
| + | 
| + auto factory = static_cast<net::HttpAuthHandlerRegistryFactory*>( | 
| + peer.io_thread()->globals()->http_auth_handler_factory.get()); | 
| + | 
| + auto negotiate_factory = static_cast<net::HttpAuthHandlerNegotiate::Factory*>( | 
| + factory->GetSchemeFactory(net::kNegotiateAuthScheme)); | 
| + // If we don't have a negotiate factory (net wasn't built with Kerberos) the | 
| + // policy does nothing so we can't test anything. | 
| + if (!negotiate_factory) | 
| + return; | 
| + | 
| + peer.pref_service()->SetString(prefs::kAuthAndroidNegotiateAccountType, | 
| + "acc1"); | 
| + EXPECT_EQ("acc1", *(negotiate_factory->library())); | 
| + peer.pref_service()->SetString(prefs::kAuthAndroidNegotiateAccountType, | 
| + "acc2"); | 
| + EXPECT_EQ("acc2", *(negotiate_factory->library())); | 
| +} | 
| +#endif | 
| + | 
| } // namespace test |