diff options
author | bryner@chromium.org <bryner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 21:27:18 +0000 |
---|---|---|
committer | bryner@chromium.org <bryner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 21:27:18 +0000 |
commit | d03c658c4baabe124e5eb3e540f13da296d64d8a (patch) | |
tree | e53ea1a91028120d7279ca13024b3444b5ecb364 /chrome/renderer/safe_browsing | |
parent | d7b593ce2ad258ac6c7811da7f364affe89fb0c9 (diff) | |
download | chromium_src-d03c658c4baabe124e5eb3e540f13da296d64d8a.zip chromium_src-d03c658c4baabe124e5eb3e540f13da296d64d8a.tar.gz chromium_src-d03c658c4baabe124e5eb3e540f13da296d64d8a.tar.bz2 |
Factor out the setup for PhishingDOMFeatureExtractorTest into a new base class.
This setup will be shared by an upcoming higher-level test of client-side
phishing detection. This change also removes the logic to use a unique thread
name for each TEST_F; this is redundant now that each test runs in its own
process.
TEST=PhishingDOMFeatureExtractorTest still passes
BUG=none
Review URL: http://codereview.chromium.org/3253004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58402 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/safe_browsing')
3 files changed, 312 insertions, 196 deletions
diff --git a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc index 995ba01..b05ec5f 100644 --- a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc @@ -9,62 +9,20 @@ #include "chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h" -#include <string.h> // for memcpy() -#include <map> -#include <string> - #include "base/callback.h" -#include "base/command_line.h" #include "base/message_loop.h" -#include "base/process.h" -#include "base/string_util.h" #include "base/time.h" -#include "chrome/common/main_function_params.h" -#include "chrome/common/render_messages.h" -#include "chrome/common/render_messages_params.h" -#include "chrome/common/sandbox_init_wrapper.h" -#include "chrome/renderer/mock_render_process.h" -#include "chrome/renderer/render_thread.h" -#include "chrome/renderer/render_view.h" -#include "chrome/renderer/render_view_visitor.h" -#include "chrome/renderer/renderer_main_platform_delegate.h" #include "chrome/renderer/safe_browsing/feature_extractor_clock.h" #include "chrome/renderer/safe_browsing/features.h" -#include "googleurl/src/gurl.h" -#include "ipc/ipc_channel.h" -#include "net/base/upload_data.h" -#include "net/http/http_response_headers.h" +#include "chrome/renderer/safe_browsing/render_view_fake_resources_test.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" -#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" -#include "third_party/WebKit/WebKit/chromium/public/WebView.h" -#include "webkit/glue/webkit_glue.h" using ::testing::ContainerEq; using ::testing::Return; namespace safe_browsing { -class PhishingDOMFeatureExtractorTest : public ::testing::Test, - public IPC::Channel::Listener, - public RenderViewVisitor { - public: - // IPC::Channel::Listener implementation. - virtual void OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(PhishingDOMFeatureExtractorTest, message) - IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady) - IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading) - IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) - IPC_END_MESSAGE_MAP() - } - - // RenderViewVisitor implementation. - virtual bool Visit(RenderView* render_view) { - view_ = render_view; - return false; - } - +class PhishingDOMFeatureExtractorTest : public RenderViewFakeResourcesTest { protected: class MockClock : public FeatureExtractorClock { public: @@ -72,73 +30,15 @@ class PhishingDOMFeatureExtractorTest : public ::testing::Test, }; virtual void SetUp() { - // Set up the renderer. This code is largely adapted from - // render_view_test.cc and renderer_main.cc. Note that we use a - // MockRenderProcess (because we don't need to use IPC for painting), - // but we use a real RenderThread so that we can use the ResourceDispatcher - // to fetch network resources. These are then served canned content - // in OnRequestResource(). - sandbox_init_wrapper_.reset(new SandboxInitWrapper); - command_line_.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY)); - params_.reset(new MainFunctionParams(*command_line_, - *sandbox_init_wrapper_, NULL)); - platform_.reset(new RendererMainPlatformDelegate(*params_)); - platform_->PlatformInitialize(); - - std::string thread_name = GetNextThreadName(); - channel_.reset(new IPC::Channel(thread_name, - IPC::Channel::MODE_SERVER, this)); - ASSERT_TRUE(channel_->Connect()); - - webkit_glue::SetJavaScriptFlags("--expose-gc"); - mock_process_.reset(new MockRenderProcess); - render_thread_ = new RenderThread(thread_name); - mock_process_->set_main_thread(render_thread_); - - // Tell the renderer to create a view, then wait until it's ready. - // We can't call View::Create() directly here or else we won't get - // RenderProcess's lazy initialization of WebKit. - view_ = NULL; - ViewMsg_New_Params params; - params.parent_window = 0; - params.view_id = kViewId; - params.session_storage_namespace_id = kInvalidSessionStorageNamespaceId; - ASSERT_TRUE(channel_->Send(new ViewMsg_New(params))); - msg_loop_.Run(); + // Set up WebKit and the RenderView. + RenderViewFakeResourcesTest::SetUp(); clock_ = new MockClock(); extractor_.reset(new PhishingDOMFeatureExtractor(view_, clock_)); } virtual void TearDown() { - // Try very hard to collect garbage before shutting down. - GetMainFrame()->collectGarbage(); - GetMainFrame()->collectGarbage(); - - ASSERT_TRUE(channel_->Send(new ViewMsg_Close(kViewId))); - do { - msg_loop_.RunAllPending(); - view_ = NULL; - RenderView::ForEach(this); - } while (view_); - - mock_process_.reset(); - msg_loop_.RunAllPending(); - platform_->PlatformUninitialize(); - platform_.reset(); - command_line_.reset(); - sandbox_init_wrapper_.reset(); - } - - // Returns the main WebFrame for our RenderView. - WebKit::WebFrame* GetMainFrame() { - return view_->webview()->mainFrame(); - } - - // Loads |url| into the RenderView, waiting for the load to finish. - void LoadURL(const std::string& url) { - GetMainFrame()->loadRequest(WebKit::WebURLRequest(GURL(url))); - msg_loop_.Run(); + RenderViewFakeResourcesTest::TearDown(); } // Runs the DOMFeatureExtractor on the RenderView, waiting for the @@ -148,110 +48,21 @@ class PhishingDOMFeatureExtractorTest : public ::testing::Test, extractor_->ExtractFeatures( features, NewCallback(this, &PhishingDOMFeatureExtractorTest::ExtractionDone)); - msg_loop_.Run(); + message_loop_.Run(); return success_; } // Completion callback for feature extraction. void ExtractionDone(bool success) { success_ = success; - msg_loop_.Quit(); - } - - // IPC message handlers below - - // Notification that page load has finished. Exit the message loop - // so that the test can continue. - void OnDidStopLoading() { - msg_loop_.Quit(); - } - - // Notification that the renderer wants to load a resource. - // If the requested url is in responses_, we send the renderer a 200 - // and the supplied content, otherwise we send it a 404 error. - void OnRequestResource(const IPC::Message& message, - int request_id, - const ViewHostMsg_Resource_Request& request_data) { - std::string headers, body; - std::map<std::string, std::string>::const_iterator it = - responses_.find(request_data.url.spec()); - if (it == responses_.end()) { - headers = "HTTP/1.1 404 Not Found\0Content-Type:text/html\0\0"; - body = "content not found"; - } else { - headers = "HTTP/1.1 200 OK\0Content-Type:text/html\0\0"; - body = it->second; - } - - ResourceResponseHead response_head; - response_head.headers = new net::HttpResponseHeaders(headers); - response_head.mime_type = "text/html"; - ASSERT_TRUE(channel_->Send(new ViewMsg_Resource_ReceivedResponse( - message.routing_id(), request_id, response_head))); - - base::SharedMemory shared_memory; - ASSERT_TRUE(shared_memory.Create(std::wstring(), false, - false, body.size())); - ASSERT_TRUE(shared_memory.Map(body.size())); - memcpy(shared_memory.memory(), body.data(), body.size()); - - base::SharedMemoryHandle handle; - ASSERT_TRUE(shared_memory.GiveToProcess(base::Process::Current().handle(), - &handle)); - ASSERT_TRUE(channel_->Send(new ViewMsg_Resource_DataReceived( - message.routing_id(), request_id, handle, body.size()))); - - ASSERT_TRUE(channel_->Send(new ViewMsg_Resource_RequestComplete( - message.routing_id(), - request_id, - URLRequestStatus(), - std::string()))); - } - - // Notification that the render view we've created is ready to use. - void OnRenderViewReady() { - // Grab a pointer to the new view using RenderViewVisitor. - ASSERT_TRUE(!view_); - RenderView::ForEach(this); - ASSERT_TRUE(view_); - msg_loop_.Quit(); - } - - // We use a new IPC channel name for each test that runs. - // This is necessary because the renderer-side IPC channel is not - // shut down when the RenderThread goes away, so attempting to reuse - // the channel name gives an error (see ChildThread::~ChildThread()). - static std::string GetNextThreadName() { - return StringPrintf( - "phishing_dom_feature_Extractor_unittest.%d", - next_thread_id_++); + message_loop_.Quit(); } - static int next_thread_id_; // incrementing counter for thread ids - static const int32 kViewId = 5; // arbitrary id for our testing view - - MessageLoopForIO msg_loop_; - // channel that the renderer uses to talk to the browser. - // For this test, we will handle the browser end of the channel. - scoped_ptr<IPC::Channel> channel_; - RenderThread* render_thread_; // owned by mock_process_ - scoped_ptr<MockRenderProcess> mock_process_; - RenderView* view_; // not owned, deletes itself on close - scoped_ptr<RendererMainPlatformDelegate> platform_; - scoped_ptr<MainFunctionParams> params_; - scoped_ptr<CommandLine> command_line_; - scoped_ptr<SandboxInitWrapper> sandbox_init_wrapper_; - scoped_ptr<PhishingDOMFeatureExtractor> extractor_; MockClock* clock_; // owned by extractor_ - // Map of URL -> response body for network requests from the renderer. - // Any URLs not in this map are served a 404 error. - std::map<std::string, std::string> responses_; bool success_; // holds the success value from ExtractFeatures }; -int PhishingDOMFeatureExtractorTest::next_thread_id_ = 0; - TEST_F(PhishingDOMFeatureExtractorTest, FormFeatures) { // This test doesn't exercise the extraction timing. EXPECT_CALL(*clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now())); diff --git a/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc b/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc new file mode 100644 index 0000000..dc9583a --- /dev/null +++ b/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc @@ -0,0 +1,169 @@ +// Copyright (c) 2010 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/renderer/safe_browsing/render_view_fake_resources_test.h" + +#include <string.h> + +#include "base/command_line.h" +#include "base/process.h" +#include "base/shared_memory.h" +#include "chrome/common/dom_storage_common.h" +#include "chrome/common/main_function_params.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/render_messages_params.h" +#include "chrome/common/resource_response.h" +#include "chrome/common/sandbox_init_wrapper.h" +#include "chrome/renderer/mock_render_process.h" +#include "chrome/renderer/render_thread.h" +#include "chrome/renderer/render_view.h" +#include "chrome/renderer/renderer_main_platform_delegate.h" +#include "googleurl/src/gurl.h" +#include "net/base/upload_data.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_request_status.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" +#include "webkit/glue/webkit_glue.h" + +namespace safe_browsing { + +const int32 RenderViewFakeResourcesTest::kViewId = 5; + +RenderViewFakeResourcesTest::RenderViewFakeResourcesTest() {} +RenderViewFakeResourcesTest::~RenderViewFakeResourcesTest() {} + +void RenderViewFakeResourcesTest::OnMessageReceived( + const IPC::Message& message) { + IPC_BEGIN_MESSAGE_MAP(RenderViewFakeResourcesTest, message) + IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady) + IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading) + IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) + IPC_END_MESSAGE_MAP() +} + +bool RenderViewFakeResourcesTest::Visit(RenderView* render_view) { + view_ = render_view; + return false; +} + +void RenderViewFakeResourcesTest::SetUp() { + // Set up the renderer. This code is largely adapted from + // render_view_test.cc and renderer_main.cc. Note that we use a + // MockRenderProcess (because we don't need to use IPC for painting), + // but we use a real RenderThread so that we can use the ResourceDispatcher + // to fetch network resources. These are then served canned content + // in OnRequestResource(). + sandbox_init_wrapper_.reset(new SandboxInitWrapper); + command_line_.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY)); + params_.reset(new MainFunctionParams(*command_line_, + *sandbox_init_wrapper_, NULL)); + platform_.reset(new RendererMainPlatformDelegate(*params_)); + platform_->PlatformInitialize(); + + static const char kThreadName[] = "RenderViewFakeResourcesTest"; + channel_.reset(new IPC::Channel(kThreadName, + IPC::Channel::MODE_SERVER, this)); + ASSERT_TRUE(channel_->Connect()); + + webkit_glue::SetJavaScriptFlags("--expose-gc"); + mock_process_.reset(new MockRenderProcess); + render_thread_ = new RenderThread(kThreadName); + mock_process_->set_main_thread(render_thread_); + + // Tell the renderer to create a view, then wait until it's ready. + // We can't call View::Create() directly here or else we won't get + // RenderProcess's lazy initialization of WebKit. + view_ = NULL; + ViewMsg_New_Params params; + params.parent_window = 0; + params.view_id = kViewId; + params.session_storage_namespace_id = kInvalidSessionStorageNamespaceId; + ASSERT_TRUE(channel_->Send(new ViewMsg_New(params))); + message_loop_.Run(); +} + +void RenderViewFakeResourcesTest::TearDown() { + // Try very hard to collect garbage before shutting down. + GetMainFrame()->collectGarbage(); + GetMainFrame()->collectGarbage(); + + ASSERT_TRUE(channel_->Send(new ViewMsg_Close(kViewId))); + do { + message_loop_.RunAllPending(); + view_ = NULL; + RenderView::ForEach(this); + } while (view_); + + mock_process_.reset(); + message_loop_.RunAllPending(); + platform_->PlatformUninitialize(); + platform_.reset(); + command_line_.reset(); + sandbox_init_wrapper_.reset(); +} + +WebKit::WebFrame* RenderViewFakeResourcesTest::GetMainFrame() { + return view_->webview()->mainFrame(); +} + +void RenderViewFakeResourcesTest::LoadURL(const std::string& url) { + GetMainFrame()->loadRequest(WebKit::WebURLRequest(GURL(url))); + message_loop_.Run(); +} + +void RenderViewFakeResourcesTest::OnDidStopLoading() { + message_loop_.Quit(); +} + +void RenderViewFakeResourcesTest::OnRequestResource( + const IPC::Message& message, + int request_id, + const ViewHostMsg_Resource_Request& request_data) { + std::string headers, body; + std::map<std::string, std::string>::const_iterator it = + responses_.find(request_data.url.spec()); + if (it == responses_.end()) { + headers = "HTTP/1.1 404 Not Found\0Content-Type:text/html\0\0"; + body = "content not found"; + } else { + headers = "HTTP/1.1 200 OK\0Content-Type:text/html\0\0"; + body = it->second; + } + + ResourceResponseHead response_head; + response_head.headers = new net::HttpResponseHeaders(headers); + response_head.mime_type = "text/html"; + ASSERT_TRUE(channel_->Send(new ViewMsg_Resource_ReceivedResponse( + message.routing_id(), request_id, response_head))); + + base::SharedMemory shared_memory; + ASSERT_TRUE(shared_memory.Create(std::wstring(), false, + false, body.size())); + ASSERT_TRUE(shared_memory.Map(body.size())); + memcpy(shared_memory.memory(), body.data(), body.size()); + + base::SharedMemoryHandle handle; + ASSERT_TRUE(shared_memory.GiveToProcess(base::Process::Current().handle(), + &handle)); + ASSERT_TRUE(channel_->Send(new ViewMsg_Resource_DataReceived( + message.routing_id(), request_id, handle, body.size()))); + + ASSERT_TRUE(channel_->Send(new ViewMsg_Resource_RequestComplete( + message.routing_id(), + request_id, + URLRequestStatus(), + std::string()))); +} + +void RenderViewFakeResourcesTest::OnRenderViewReady() { + // Grab a pointer to the new view using RenderViewVisitor. + ASSERT_TRUE(!view_); + RenderView::ForEach(this); + ASSERT_TRUE(view_); + message_loop_.Quit(); +} + +} // namespace safe_browsing diff --git a/chrome/renderer/safe_browsing/render_view_fake_resources_test.h b/chrome/renderer/safe_browsing/render_view_fake_resources_test.h new file mode 100644 index 0000000..4e91cf5 --- /dev/null +++ b/chrome/renderer/safe_browsing/render_view_fake_resources_test.h @@ -0,0 +1,136 @@ +// Copyright (c) 2010 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. +// +// RenderViewFakeResourcesTest can be used as a base class for tests that need +// to simulate loading network resources (such as http: urls) into a +// RenderView. It does this by handling the relevant IPC messages that the +// renderer would normally send to the browser, and responding with static +// content from an internal map. A request for a url that is not in the map +// will return a 404. Currently, content is always returned as text/html, and +// there is no support for handling POST data. +// +// RenderViewFakeResourcesTest sets up a MessageLoop (message_loop_) that +// can be used by the subclass to post or process tasks. +// +// Note that since WebKit cannot be safely shut down and re-initialized, +// any test that uses this base class should run as part of browser_tests +// so that the test is launched in its own process. +// +// Typical usage: +// +// class MyTest : public RenderVieFakeResourcesTest { +// protected: +// virtual void SetUp() { +// RenderViewFakeResourcesTest::SetUp(); +// <insert test-specific setup> +// } +// +// virtual void TearDown() { +// <insert test-specific teardown> +// RenderViewFakeResourcesTest::TearDown(); +// } +// ... +// }; +// +// TEST_F(MyTest, TestFoo) { +// responses_["http://host.com/"] = "<html><body>some content</body></html>"; +// LoadURL("http://host.com/"); +// ... +// } + +#ifndef CHROME_RENDERER_SAFE_BROWSING_RENDER_VIEW_FAKE_RESOURCES_TEST_H_ +#define CHROME_RENDERER_SAFE_BROWSING_RENDER_VIEW_FAKE_RESOURCES_TEST_H_ + +#include <map> +#include <string> + +#include "base/message_loop.h" +#include "base/scoped_ptr.h" +#include "chrome/renderer/render_view_visitor.h" +#include "ipc/ipc_channel.h" +#include "testing/gtest/include/gtest/gtest.h" + +class CommandLine; +class MockRenderProcess; +class RendererMainPlatformDelegate; +class RenderThread; +class RenderView; +class SandboxInitWrapper; +struct MainFunctionParams; +struct ViewHostMsg_Resource_Request; + +namespace WebKit { +class WebFrame; +} + +namespace safe_browsing { + +class RenderViewFakeResourcesTest : public ::testing::Test, + public IPC::Channel::Listener, + public RenderViewVisitor { + public: + // IPC::Channel::Listener implementation. + virtual void OnMessageReceived(const IPC::Message& message); + + // RenderViewVisitor implementation. + virtual bool Visit(RenderView* render_view); + + protected: + RenderViewFakeResourcesTest(); + virtual ~RenderViewFakeResourcesTest(); + + // Call the base class SetUp and TearDown methods as part of your + // test fixture's SetUp / TearDown. + virtual void SetUp(); + virtual void TearDown(); + + // Loads |url| into the RenderView, waiting for the load to finish. + // Before loading the url, add any content that you want to return + // to responses_. + void LoadURL(const std::string& url); + + // Returns the main WebFrame for our RenderView. + WebKit::WebFrame* GetMainFrame(); + + // IPC message handlers below + + // Notification that page load has finished. Exit the message loop + // so that the test can continue. + void OnDidStopLoading(); + + // Notification that the renderer wants to load a resource. + // If the requested url is in responses_, we send the renderer a 200 + // and the supplied content, otherwise we send it a 404 error. + void OnRequestResource(const IPC::Message& message, + int request_id, + const ViewHostMsg_Resource_Request& request_data); + + // Notification that the render view we've created is ready to use. + void OnRenderViewReady(); + + static const int32 kViewId; // arbitrary id for our testing view + + MessageLoopForIO message_loop_; + // channel that the renderer uses to talk to the browser. + // For this test, we will handle the browser end of the channel. + scoped_ptr<IPC::Channel> channel_; + RenderThread* render_thread_; // owned by mock_process_ + scoped_ptr<MockRenderProcess> mock_process_; + RenderView* view_; // not owned, deletes itself on close + scoped_ptr<RendererMainPlatformDelegate> platform_; + scoped_ptr<MainFunctionParams> params_; + scoped_ptr<CommandLine> command_line_; + scoped_ptr<SandboxInitWrapper> sandbox_init_wrapper_; + + // Map of url -> response body for network requests from the renderer. + // Any urls not in this map are served a 404 error. + std::map<std::string, std::string> responses_; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderViewFakeResourcesTest); +}; + +} // namespace safe_browsing + +#endif // CHROME_RENDERER_SAFE_BROWSING_RENDER_VIEW_FAKE_RESOURCES_TEST_H_ |