diff options
19 files changed, 400 insertions, 143 deletions
diff --git a/apps/shell/app_shell.gyp b/apps/shell/app_shell.gyp index 121df007..de0a74d 100644 --- a/apps/shell/app_shell.gyp +++ b/apps/shell/app_shell.gyp @@ -202,6 +202,7 @@ '<(DEPTH)/content/content.gyp:content_app_both', '<(DEPTH)/content/content_shell_and_tests.gyp:content_browser_test_support', '<(DEPTH)/content/content_shell_and_tests.gyp:test_support_content', + '<(DEPTH)/extensions/extensions.gyp:extensions_test_support', '<(DEPTH)/testing/gtest.gyp:gtest', ], 'defines': [ @@ -209,6 +210,7 @@ ], 'sources': [ # TODO(yoz): Refactor once we have a second test target. + 'browser/dns_apitest.cc', 'browser/shell_browsertest.cc', 'test/shell_test.h', 'test/shell_test.cc', diff --git a/apps/shell/browser/DEPS b/apps/shell/browser/DEPS index 0b6fca2..dc74d1d 100644 --- a/apps/shell/browser/DEPS +++ b/apps/shell/browser/DEPS @@ -16,6 +16,9 @@ include_rules = [ "+content/shell/browser/shell_devtools_delegate.h", "+content/shell/browser/shell_net_log.h", + # Only used in API tests that should be moved to extensions/browser/api/... + "+net", + "+sync/api", # Disallow views to keep the binary size down. diff --git a/apps/shell/browser/dns_apitest.cc b/apps/shell/browser/dns_apitest.cc new file mode 100644 index 0000000..96736ea --- /dev/null +++ b/apps/shell/browser/dns_apitest.cc @@ -0,0 +1,128 @@ +// Copyright 2014 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 "apps/shell/test/shell_test.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "extensions/browser/api/dns/dns_api.h" +#include "extensions/browser/api/dns/host_resolver_wrapper.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" +#include "extensions/browser/api_test_utils.h" +#include "extensions/browser/extension_function_dispatcher.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_builder.h" +#include "net/base/net_errors.h" + +using extensions::ExtensionFunctionDispatcher; +using extensions::api_test_utils::RunFunctionAndReturnSingleResult; + +namespace { + +class TestFunctionDispatcherDelegate + : public ExtensionFunctionDispatcher::Delegate { + public: + TestFunctionDispatcherDelegate() {} + virtual ~TestFunctionDispatcherDelegate() {} + + // NULL implementation. + private: + DISALLOW_COPY_AND_ASSIGN(TestFunctionDispatcherDelegate); +}; + +} // namespace + +class DnsApiTest : public apps::AppShellTest { + public: + DnsApiTest() : resolver_creator_(new extensions::MockHostResolverCreator()) {} + + private: + virtual void SetUpOnMainThread() OVERRIDE { + apps::AppShellTest::SetUpOnMainThread(); + extensions::HostResolverWrapper::GetInstance()->SetHostResolverForTesting( + resolver_creator_->CreateMockHostResolver()); + } + + virtual void TearDownOnMainThread() OVERRIDE { + extensions::HostResolverWrapper::GetInstance()->SetHostResolverForTesting( + NULL); + resolver_creator_->DeleteMockHostResolver(); + apps::AppShellTest::TearDownOnMainThread(); + } + + // The MockHostResolver asserts that it's used on the same thread on which + // it's created, which is actually a stronger rule than its real counterpart. + // But that's fine; it's good practice. + scoped_refptr<extensions::MockHostResolverCreator> resolver_creator_; +}; + +IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsResolveIPLiteral) { + scoped_refptr<extensions::DnsResolveFunction> resolve_function( + new extensions::DnsResolveFunction()); + scoped_refptr<extensions::Extension> empty_extension( + extensions::ExtensionBuilder() + .SetManifest(extensions::DictionaryBuilder().Set("name", "Test").Set( + "version", "1.0")) + .Build()); + + resolve_function->set_extension(empty_extension.get()); + resolve_function->set_has_callback(true); + + TestFunctionDispatcherDelegate delegate; + scoped_ptr<ExtensionFunctionDispatcher> dispatcher( + new ExtensionFunctionDispatcher(browser_context(), &delegate)); + + scoped_ptr<base::Value> result( + RunFunctionAndReturnSingleResult(resolve_function.get(), + "[\"127.0.0.1\"]", + browser_context(), + dispatcher.Pass())); + base::DictionaryValue* dict = NULL; + ASSERT_TRUE(result->GetAsDictionary(&dict)); + + int result_code = 0; + EXPECT_TRUE(dict->GetInteger("resultCode", &result_code)); + EXPECT_EQ(net::OK, result_code); + + std::string address; + EXPECT_TRUE(dict->GetString("address", &address)); + EXPECT_EQ("127.0.0.1", address); +} + +IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsResolveHostname) { + scoped_refptr<extensions::DnsResolveFunction> resolve_function( + new extensions::DnsResolveFunction()); + scoped_refptr<extensions::Extension> empty_extension( + extensions::ExtensionBuilder() + .SetManifest(extensions::DictionaryBuilder().Set("name", "Test").Set( + "version", "1.0")) + .Build()); + + resolve_function->set_extension(empty_extension.get()); + resolve_function->set_has_callback(true); + + TestFunctionDispatcherDelegate delegate; + scoped_ptr<ExtensionFunctionDispatcher> dispatcher( + new ExtensionFunctionDispatcher(browser_context(), &delegate)); + + std::string function_arguments("[\""); + function_arguments += extensions::MockHostResolverCreator::kHostname; + function_arguments += "\"]"; + scoped_ptr<base::Value> result( + RunFunctionAndReturnSingleResult(resolve_function.get(), + function_arguments, + browser_context(), + dispatcher.Pass())); + base::DictionaryValue* dict = NULL; + ASSERT_TRUE(result->GetAsDictionary(&dict)); + + int result_code = 0; + EXPECT_TRUE(dict->GetInteger("resultCode", &result_code)); + EXPECT_EQ(net::OK, result_code); + + std::string address; + EXPECT_TRUE(dict->GetString("address", &address)); + EXPECT_EQ(extensions::MockHostResolverCreator::kAddress, address); +} diff --git a/chrome/browser/extensions/api/dns/dns_apitest.cc b/chrome/browser/extensions/api/dns/dns_apitest.cc index 0918425..52448ca 100644 --- a/chrome/browser/extensions/api/dns/dns_apitest.cc +++ b/chrome/browser/extensions/api/dns/dns_apitest.cc @@ -3,35 +3,18 @@ // found in the LICENSE file. #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h" #include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/extensions/extension_function_test_utils.h" -#include "extensions/browser/api/dns/dns_api.h" #include "extensions/browser/api/dns/host_resolver_wrapper.h" -#include "extensions/common/switches.h" -#include "net/base/net_errors.h" -#include "net/base/net_util.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" #include "net/dns/mock_host_resolver.h" -using extension_function_test_utils::CreateEmptyExtension; -using extension_function_test_utils::RunFunctionAndReturnSingleResult; - -namespace { - class DnsApiTest : public ExtensionApiTest { public: - DnsApiTest() : resolver_event_(true, false), - resolver_creator_(new extensions::MockHostResolverCreator()) { - } - - virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { - ExtensionApiTest::SetUpCommandLine(command_line); - command_line->AppendSwitch( - extensions::switches::kEnableExperimentalExtensionApis); - } + DnsApiTest() : resolver_creator_(new extensions::MockHostResolverCreator()) {} + private: virtual void SetUpOnMainThread() OVERRIDE { + ExtensionApiTest::SetUpOnMainThread(); extensions::HostResolverWrapper::GetInstance()->SetHostResolverForTesting( resolver_creator_->CreateMockHostResolver()); } @@ -40,69 +23,15 @@ class DnsApiTest : public ExtensionApiTest { extensions::HostResolverWrapper::GetInstance()-> SetHostResolverForTesting(NULL); resolver_creator_->DeleteMockHostResolver(); + ExtensionApiTest::CleanUpOnMainThread(); } - private: - base::WaitableEvent resolver_event_; - // The MockHostResolver asserts that it's used on the same thread on which // it's created, which is actually a stronger rule than its real counterpart. // But that's fine; it's good practice. scoped_refptr<extensions::MockHostResolverCreator> resolver_creator_; }; -} // namespace - -IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsResolveIPLiteral) { - scoped_refptr<extensions::DnsResolveFunction> resolve_function( - new extensions::DnsResolveFunction()); - scoped_refptr<extensions::Extension> empty_extension(CreateEmptyExtension()); - - resolve_function->set_extension(empty_extension.get()); - resolve_function->set_has_callback(true); - - scoped_ptr<base::Value> result(RunFunctionAndReturnSingleResult( - resolve_function.get(), "[\"127.0.0.1\"]", browser())); - ASSERT_EQ(base::Value::TYPE_DICTIONARY, result->GetType()); - base::DictionaryValue *value = - static_cast<base::DictionaryValue*>(result.get()); - - int resultCode; - EXPECT_TRUE(value->GetInteger("resultCode", &resultCode)); - EXPECT_EQ(net::OK, resultCode); - - std::string address; - EXPECT_TRUE(value->GetString("address", &address)); - EXPECT_EQ("127.0.0.1", address); -} - -IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsResolveHostname) { - scoped_refptr<extensions::DnsResolveFunction> resolve_function( - new extensions::DnsResolveFunction()); - scoped_refptr<extensions::Extension> empty_extension(CreateEmptyExtension()); - - resolve_function->set_extension(empty_extension.get()); - resolve_function->set_has_callback(true); - - std::string function_arguments("[\""); - function_arguments += extensions::MockHostResolverCreator::kHostname; - function_arguments += "\"]"; - scoped_ptr<base::Value> result( - RunFunctionAndReturnSingleResult(resolve_function.get(), - function_arguments, browser())); - ASSERT_EQ(base::Value::TYPE_DICTIONARY, result->GetType()); - base::DictionaryValue *value = - static_cast<base::DictionaryValue*>(result.get()); - - int resultCode; - EXPECT_TRUE(value->GetInteger("resultCode", &resultCode)); - EXPECT_EQ(net::OK, resultCode); - - std::string address; - EXPECT_TRUE(value->GetString("address", &address)); - EXPECT_EQ(extensions::MockHostResolverCreator::kAddress, address); -} - IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsExtension) { ASSERT_TRUE(RunExtensionTest("dns/api")) << message_; } diff --git a/chrome/browser/extensions/api/socket/socket_apitest.cc b/chrome/browser/extensions/api/socket/socket_apitest.cc index 440c526..718eea0 100644 --- a/chrome/browser/extensions/api/socket/socket_apitest.cc +++ b/chrome/browser/extensions/api/socket/socket_apitest.cc @@ -4,7 +4,6 @@ #include "base/memory/ref_counted.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service.h" @@ -14,6 +13,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "extensions/browser/api/dns/host_resolver_wrapper.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" #include "extensions/browser/api/socket/socket_api.h" #include "net/dns/mock_host_resolver.h" #include "net/test/spawned_test_server/spawned_test_server.h" diff --git a/chrome/browser/extensions/api/sockets_tcp/sockets_tcp_apitest.cc b/chrome/browser/extensions/api/sockets_tcp/sockets_tcp_apitest.cc index 0b419ad..8159fe3 100644 --- a/chrome/browser/extensions/api/sockets_tcp/sockets_tcp_apitest.cc +++ b/chrome/browser/extensions/api/sockets_tcp/sockets_tcp_apitest.cc @@ -5,7 +5,6 @@ #include "base/memory/ref_counted.h" #include "base/path_service.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service.h" @@ -16,6 +15,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "extensions/browser/api/dns/host_resolver_wrapper.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" #include "extensions/browser/api/sockets_tcp/sockets_tcp_api.h" #include "net/dns/mock_host_resolver.h" #include "net/test/spawned_test_server/spawned_test_server.h" diff --git a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_apitest.cc b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_apitest.cc index f4a4006..8b9a7ab 100644 --- a/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_apitest.cc +++ b/chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_apitest.cc @@ -5,7 +5,6 @@ #include "base/memory/ref_counted.h" #include "base/path_service.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service.h" @@ -16,6 +15,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "extensions/browser/api/dns/host_resolver_wrapper.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" #include "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h" #include "net/dns/mock_host_resolver.h" #include "net/test/spawned_test_server/spawned_test_server.h" diff --git a/chrome/browser/extensions/api/sockets_udp/sockets_udp_apitest.cc b/chrome/browser/extensions/api/sockets_udp/sockets_udp_apitest.cc index 0f203c7..2e80122 100644 --- a/chrome/browser/extensions/api/sockets_udp/sockets_udp_apitest.cc +++ b/chrome/browser/extensions/api/sockets_udp/sockets_udp_apitest.cc @@ -5,7 +5,6 @@ #include "base/memory/ref_counted.h" #include "base/path_service.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service.h" @@ -17,6 +16,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "extensions/browser/api/dns/host_resolver_wrapper.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" #include "extensions/browser/api/sockets_udp/sockets_udp_api.h" #include "net/dns/mock_host_resolver.h" #include "net/test/spawned_test_server/spawned_test_server.h" diff --git a/chrome/browser/extensions/extension_function_test_utils.cc b/chrome/browser/extensions/extension_function_test_utils.cc index 94951ca..d3990c3 100644 --- a/chrome/browser/extensions/extension_function_test_utils.cc +++ b/chrome/browser/extensions/extension_function_test_utils.cc @@ -13,6 +13,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/ui_test_utils.h" +#include "extensions/browser/api_test_utils.h" #include "extensions/browser/extension_function.h" #include "extensions/browser/extension_function_dispatcher.h" #include "extensions/common/extension.h" @@ -55,20 +56,18 @@ base::Value* ParseJSON(const std::string& data) { } base::ListValue* ParseList(const std::string& data) { - scoped_ptr<base::Value> result(ParseJSON(data)); - if (result.get() && result->IsType(base::Value::TYPE_LIST)) - return static_cast<base::ListValue*>(result.release()); - else - return NULL; + base::Value* result = ParseJSON(data); + base::ListValue* list = NULL; + result->GetAsList(&list); + return list; } base::DictionaryValue* ParseDictionary( const std::string& data) { - scoped_ptr<base::Value> result(ParseJSON(data)); - if (result.get() && result->IsType(base::Value::TYPE_DICTIONARY)) - return static_cast<base::DictionaryValue*>(result.release()); - else - return NULL; + base::Value* result = ParseJSON(data); + base::DictionaryValue* dict = NULL; + result->GetAsDictionary(&dict); + return dict; } bool GetBoolean(base::DictionaryValue* val, const std::string& key) { @@ -243,31 +242,18 @@ bool RunFunction(UIThreadExtensionFunction* function, const std::string& args, Browser* browser, RunFunctionFlags flags) { - SendResponseDelegate response_delegate; - function->set_test_delegate(&response_delegate); - scoped_ptr<base::ListValue> parsed_args(ParseList(args)); - EXPECT_TRUE(parsed_args.get()) << - "Could not parse extension function arguments: " << args; - function->SetArgs(parsed_args.get()); - TestFunctionDispatcherDelegate dispatcher_delegate(browser); - extensions::ExtensionFunctionDispatcher dispatcher(browser->profile(), - &dispatcher_delegate); - function->set_dispatcher(dispatcher.AsWeakPtr()); - - function->set_browser_context(browser->profile()); - function->set_include_incognito(flags & INCLUDE_INCOGNITO); - function->Run()->Execute(); - - // If the RunAsync of |function| didn't already call SendResponse, run the - // message loop until they do. - if (!response_delegate.HasResponse()) { - response_delegate.set_should_post_quit(true); - content::RunMessageLoop(); - } - - EXPECT_TRUE(response_delegate.HasResponse()); - return response_delegate.GetResponse(); + scoped_ptr<extensions::ExtensionFunctionDispatcher> dispatcher( + new extensions::ExtensionFunctionDispatcher(browser->profile(), + &dispatcher_delegate)); + // TODO(yoz): The cast is a hack; these flags should be defined in + // only one place. See crbug.com/394840. + return extensions::api_test_utils::RunFunction( + function, + args, + browser->profile(), + dispatcher.Pass(), + static_cast<extensions::api_test_utils::RunFunctionFlags>(flags)); } } // namespace extension_function_test_utils diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index a9f6a3f..e513d79 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1073,8 +1073,6 @@ 'browser/extensions/api/developer_private/developer_private_apitest.cc', 'browser/extensions/api/dial/dial_apitest.cc', 'browser/extensions/api/dns/dns_apitest.cc', - 'browser/extensions/api/dns/mock_host_resolver_creator.cc', - 'browser/extensions/api/dns/mock_host_resolver_creator.h', 'browser/extensions/api/downloads/downloads_api_browsertest.cc', 'browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc', 'browser/extensions/api/extension_action/browser_action_apitest.cc', diff --git a/extensions/browser/api/dns/dns_api.cc b/extensions/browser/api/dns/dns_api.cc index ef270c7..ae61123 100644 --- a/extensions/browser/api/dns/dns_api.cc +++ b/extensions/browser/api/dns/dns_api.cc @@ -49,8 +49,7 @@ void DnsResolveFunction::WorkOnIOThread() { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::HostResolver* host_resolver = - HostResolverWrapper::GetInstance()->GetHostResolver( - resource_context_->GetHostResolver()); + HostResolverWrapper::GetInstance()->GetHostResolver(resource_context_); DCHECK(host_resolver); // Yes, we are passing zero as the port. There are some interesting but not diff --git a/extensions/browser/api/dns/host_resolver_wrapper.cc b/extensions/browser/api/dns/host_resolver_wrapper.cc index f97a9c7..4a9b44e 100644 --- a/extensions/browser/api/dns/host_resolver_wrapper.cc +++ b/extensions/browser/api/dns/host_resolver_wrapper.cc @@ -4,6 +4,9 @@ #include "extensions/browser/api/dns/host_resolver_wrapper.h" +#include "content/public/browser/resource_context.h" +#include "net/dns/host_resolver.h" + namespace extensions { HostResolverWrapper::HostResolverWrapper() : resolver_(NULL) {} @@ -14,8 +17,8 @@ HostResolverWrapper* HostResolverWrapper::GetInstance() { } net::HostResolver* HostResolverWrapper::GetHostResolver( - net::HostResolver* real_resolver) { - return resolver_ ? resolver_ : real_resolver; + content::ResourceContext* context) { + return resolver_ ? resolver_ : context->GetHostResolver(); } void HostResolverWrapper::SetHostResolverForTesting( diff --git a/extensions/browser/api/dns/host_resolver_wrapper.h b/extensions/browser/api/dns/host_resolver_wrapper.h index 4eb4282..89511e4 100644 --- a/extensions/browser/api/dns/host_resolver_wrapper.h +++ b/extensions/browser/api/dns/host_resolver_wrapper.h @@ -6,7 +6,14 @@ #define EXTENSIONS_BROWSER_API_DNS_HOST_RESOLVER_WRAPPER_H_ #include "base/memory/singleton.h" -#include "net/dns/host_resolver.h" + +namespace content { +class ResourceContext; +} + +namespace net { +class HostResolver; +} namespace extensions { @@ -23,11 +30,10 @@ class HostResolverWrapper { public: static HostResolverWrapper* GetInstance(); - // Given a pointer to a real host resolver, returns the same pointer or else - // a substitute MockHostResolver to use instead. If - // SetHostResolverForTesting() hasn't been called, then this method returns - // the supplied argument as its result. - net::HostResolver* GetHostResolver(net::HostResolver* real_resolver); + // Given a pointer to a ResourceContext, returns its HostResolver if + // SetHostResolverForTesting() hasn't been called, or else a + // a substitute MockHostResolver to use instead. + net::HostResolver* GetHostResolver(content::ResourceContext* context); // Sets the MockHostResolver to return in GetHostResolver(). void SetHostResolverForTesting(net::HostResolver* mock_resolver); diff --git a/chrome/browser/extensions/api/dns/mock_host_resolver_creator.cc b/extensions/browser/api/dns/mock_host_resolver_creator.cc index 5111c3e..e2841e8 100644 --- a/chrome/browser/extensions/api/dns/mock_host_resolver_creator.cc +++ b/extensions/browser/api/dns/mock_host_resolver_creator.cc @@ -1,10 +1,10 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 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 "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h" +#include "extensions/browser/api/dns/mock_host_resolver_creator.h" -#include "chrome/test/base/in_process_browser_test.h" +#include "base/logging.h" #include "content/public/browser/browser_thread.h" #include "net/dns/mock_host_resolver.h" @@ -16,19 +16,19 @@ const std::string MockHostResolverCreator::kHostname = "www.sowbug.com"; const std::string MockHostResolverCreator::kAddress = "9.8.7.6"; MockHostResolverCreator::MockHostResolverCreator() - : resolver_event_(true, false), - mock_host_resolver_(NULL) { + : resolver_event_(true, false), mock_host_resolver_(NULL) { } MockHostResolverCreator::~MockHostResolverCreator() { } -net::MockHostResolver* MockHostResolverCreator::CreateMockHostResolver() { +net::HostResolver* MockHostResolverCreator::CreateMockHostResolver() { DCHECK(!mock_host_resolver_); DCHECK_CURRENTLY_ON(BrowserThread::UI); bool result = BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, + BrowserThread::IO, + FROM_HERE, base::Bind(&MockHostResolverCreator::CreateMockHostResolverOnIOThread, this)); DCHECK(result); @@ -52,17 +52,18 @@ void MockHostResolverCreator::DeleteMockHostResolver() { return; resolver_event_.Reset(); bool result = BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, + BrowserThread::IO, + FROM_HERE, base::Bind(&MockHostResolverCreator::DeleteMockHostResolverOnIOThread, this)); DCHECK(result); base::TimeDelta max_time = base::TimeDelta::FromSeconds(5); - ASSERT_TRUE(resolver_event_.TimedWait(max_time)); + CHECK(resolver_event_.TimedWait(max_time)); } void MockHostResolverCreator::DeleteMockHostResolverOnIOThread() { - delete(mock_host_resolver_); + delete (mock_host_resolver_); mock_host_resolver_ = NULL; resolver_event_.Signal(); } diff --git a/chrome/browser/extensions/api/dns/mock_host_resolver_creator.h b/extensions/browser/api/dns/mock_host_resolver_creator.h index bf94ccb..f57fdb8 100644 --- a/chrome/browser/extensions/api/dns/mock_host_resolver_creator.h +++ b/extensions/browser/api/dns/mock_host_resolver_creator.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2014 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 CHROME_BROWSER_EXTENSIONS_API_DNS_MOCK_HOST_RESOLVER_CREATOR_H_ -#define CHROME_BROWSER_EXTENSIONS_API_DNS_MOCK_HOST_RESOLVER_CREATOR_H_ +#ifndef EXTENSIONS_BROWSER_API_DNS_MOCK_HOST_RESOLVER_CREATOR_H_ +#define EXTENSIONS_BROWSER_API_DNS_MOCK_HOST_RESOLVER_CREATOR_H_ #include <string> @@ -11,6 +11,7 @@ #include "base/synchronization/waitable_event.h" namespace net { +class HostResolver; class MockHostResolver; } @@ -26,7 +27,7 @@ class MockHostResolverCreator MockHostResolverCreator(); - net::MockHostResolver* CreateMockHostResolver(); + net::HostResolver* CreateMockHostResolver(); void DeleteMockHostResolver(); private: @@ -48,4 +49,4 @@ class MockHostResolverCreator } // namespace extensions -#endif // CHROME_BROWSER_EXTENSIONS_API_DNS_MOCK_HOST_RESOLVER_CREATOR_H_ +#endif // EXTENSIONS_BROWSER_API_DNS_MOCK_HOST_RESOLVER_CREATOR_H_ diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index 3225827..1c41ae5 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc @@ -96,8 +96,7 @@ bool SocketExtensionWithDnsLookupFunction::PrePrepare() { void SocketExtensionWithDnsLookupFunction::StartDnsLookup( const std::string& hostname) { net::HostResolver* host_resolver = - extensions::HostResolverWrapper::GetInstance()->GetHostResolver( - resource_context_->GetHostResolver()); + HostResolverWrapper::GetInstance()->GetHostResolver(resource_context_); DCHECK(host_resolver); // Yes, we are passing zero as the port. There are some interesting but not diff --git a/extensions/browser/api_test_utils.cc b/extensions/browser/api_test_utils.cc new file mode 100644 index 0000000..4c9a58b --- /dev/null +++ b/extensions/browser/api_test_utils.cc @@ -0,0 +1,132 @@ +// Copyright 2014 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 "extensions/browser/api_test_utils.h" + +#include "base/json/json_reader.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "content/public/browser/browser_context.h" +#include "content/public/test/test_utils.h" +#include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_function_dispatcher.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +base::Value* ParseJSON(const std::string& data) { + return base::JSONReader::Read(data); +} + +base::ListValue* ParseList(const std::string& data) { + base::Value* result = ParseJSON(data); + base::ListValue* list = NULL; + result->GetAsList(&list); + return list; +} + +// This helps us be able to wait until an UIThreadExtensionFunction calls +// SendResponse. +class SendResponseDelegate + : public UIThreadExtensionFunction::DelegateForTests { + public: + SendResponseDelegate() : should_post_quit_(false) {} + + virtual ~SendResponseDelegate() {} + + void set_should_post_quit(bool should_quit) { + should_post_quit_ = should_quit; + } + + bool HasResponse() { return response_.get() != NULL; } + + bool GetResponse() { + EXPECT_TRUE(HasResponse()); + return *response_.get(); + } + + virtual void OnSendResponse(UIThreadExtensionFunction* function, + bool success, + bool bad_message) OVERRIDE { + ASSERT_FALSE(bad_message); + ASSERT_FALSE(HasResponse()); + response_.reset(new bool); + *response_ = success; + if (should_post_quit_) { + base::MessageLoopForUI::current()->Quit(); + } + } + + private: + scoped_ptr<bool> response_; + bool should_post_quit_; +}; + +} // namespace + +namespace extensions { + +namespace api_test_utils { + +base::Value* RunFunctionAndReturnSingleResult( + UIThreadExtensionFunction* function, + const std::string& args, + content::BrowserContext* context, + scoped_ptr<extensions::ExtensionFunctionDispatcher> dispatcher) { + return RunFunctionAndReturnSingleResult( + function, args, context, dispatcher.Pass(), NONE); +} + +base::Value* RunFunctionAndReturnSingleResult( + UIThreadExtensionFunction* function, + const std::string& args, + content::BrowserContext* context, + scoped_ptr<extensions::ExtensionFunctionDispatcher> dispatcher, + RunFunctionFlags flags) { + scoped_refptr<ExtensionFunction> function_owner(function); + // Without a callback the function will not generate a result. + function->set_has_callback(true); + RunFunction(function, args, context, dispatcher.Pass(), flags); + EXPECT_TRUE(function->GetError().empty()) + << "Unexpected error: " << function->GetError(); + const base::Value* single_result = NULL; + if (function->GetResultList() != NULL && + function->GetResultList()->Get(0, &single_result)) { + return single_result->DeepCopy(); + } + return NULL; +} + +bool RunFunction(UIThreadExtensionFunction* function, + const std::string& args, + content::BrowserContext* context, + scoped_ptr<extensions::ExtensionFunctionDispatcher> dispatcher, + RunFunctionFlags flags) { + SendResponseDelegate response_delegate; + function->set_test_delegate(&response_delegate); + scoped_ptr<base::ListValue> parsed_args(ParseList(args)); + EXPECT_TRUE(parsed_args.get()) + << "Could not parse extension function arguments: " << args; + function->SetArgs(parsed_args.get()); + + CHECK(dispatcher); + function->set_dispatcher(dispatcher->AsWeakPtr()); + + function->set_browser_context(context); + function->set_include_incognito(flags & INCLUDE_INCOGNITO); + function->Run()->Execute(); + + // If the RunAsync of |function| didn't already call SendResponse, run the + // message loop until they do. + if (!response_delegate.HasResponse()) { + response_delegate.set_should_post_quit(true); + content::RunMessageLoop(); + } + + EXPECT_TRUE(response_delegate.HasResponse()); + return response_delegate.GetResponse(); +} + +} // namespace api_test_utils +} // namespace extensions diff --git a/extensions/browser/api_test_utils.h b/extensions/browser/api_test_utils.h new file mode 100644 index 0000000..119b090 --- /dev/null +++ b/extensions/browser/api_test_utils.h @@ -0,0 +1,65 @@ +// Copyright 2014 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 EXTENSIONS_BROWSER_API_TEST_UTILS_H_ +#define EXTENSIONS_BROWSER_API_TEST_UTILS_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" + +class UIThreadExtensionFunction; + +namespace base { +class Value; +} + +namespace content { +class BrowserContext; +} + +namespace extensions { +class ExtensionFunctionDispatcher; + +// TODO(yoz): crbug.com/394840: Remove duplicate functionality in +// chrome/browser/extensions/extension_function_test_utils.h. +namespace api_test_utils { + +enum RunFunctionFlags { NONE = 0, INCLUDE_INCOGNITO = 1 << 0 }; + +// Run |function| with |args| and return the result. Adds an error to the +// current test if |function| returns an error. Takes ownership of +// |function|. The caller takes ownership of the result. +base::Value* RunFunctionAndReturnSingleResult( + UIThreadExtensionFunction* function, + const std::string& args, + content::BrowserContext* context, + scoped_ptr<ExtensionFunctionDispatcher> dispatcher); +base::Value* RunFunctionAndReturnSingleResult( + UIThreadExtensionFunction* function, + const std::string& args, + content::BrowserContext* context, + scoped_ptr<ExtensionFunctionDispatcher> dispatcher, + RunFunctionFlags flags); + +// Create and run |function| with |args|. Works with both synchronous and async +// functions. Ownership of |function| remains with the caller. +// +// TODO(aa): It would be nice if |args| could be validated against the schema +// that |function| expects. That way, we know that we are testing something +// close to what the bindings would actually send. +// +// TODO(aa): I'm concerned that this style won't scale to all the bits and bobs +// we're going to need to frob for all the different extension functions. But +// we can refactor when we see what is needed. +bool RunFunction(UIThreadExtensionFunction* function, + const std::string& args, + content::BrowserContext* context, + scoped_ptr<ExtensionFunctionDispatcher> dispatcher, + RunFunctionFlags flags); + +} // namespace function_test_utils +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_TEST_UTILS_H_ diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index 9c1f3a0..77a174f 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp @@ -654,6 +654,7 @@ 'type': 'static_library', 'dependencies': [ '../base/base.gyp:base', + '../net/net.gyp:net_test_support', '../testing/gtest.gyp:gtest', 'common/api/api.gyp:extensions_api', 'extensions_browser', @@ -664,6 +665,10 @@ '<(SHARED_INTERMEDIATE_DIR)', ], 'sources': [ + 'browser/api/dns/mock_host_resolver_creator.cc', + 'browser/api/dns/mock_host_resolver_creator.h', + 'browser/api_test_utils.cc', + 'browser/api_test_utils.h', 'browser/test_extensions_browser_client.cc', 'browser/test_extensions_browser_client.h', 'browser/test_management_policy.cc', |