Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / search / iframe_source_unittest.cc
blob284e8d43ee055853ab71c1006033de8e92aee84e
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/search/iframe_source.h"
7 #include "base/bind.h"
8 #include "base/memory/ref_counted_memory.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chrome/browser/search/instant_io_context.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/test/mock_resource_context.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "grit/browser_resources.h"
17 #include "ipc/ipc_message.h"
18 #include "net/base/request_priority.h"
19 #include "net/url_request/url_request.h"
20 #include "net/url_request/url_request_context.h"
21 #include "net/url_request/url_request_test_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "url/gurl.h"
25 using content::ResourceType;
27 const int kNonInstantRendererPID = 0;
28 const char kNonInstantOrigin[] = "http://evil";
29 const int kInstantRendererPID = 1;
30 const char kInstantOrigin[] = "chrome-search://instant";
31 const int kInvalidRendererPID = 42;
33 class TestIframeSource : public IframeSource {
34 public:
35 using IframeSource::GetMimeType;
36 using IframeSource::ShouldServiceRequest;
37 using IframeSource::SendResource;
38 using IframeSource::SendJSWithOrigin;
40 protected:
41 virtual std::string GetSource() const override {
42 return "test";
45 virtual bool ServesPath(const std::string& path) const override {
46 return path == "/valid.html" || path == "/valid.js";
49 virtual void StartDataRequest(
50 const std::string& path,
51 int render_process_id,
52 int render_frame_id,
53 const content::URLDataSource::GotDataCallback& callback) override {
56 // RenderFrameHost is hard to mock in concert with everything else, so stub
57 // this method out for testing.
58 virtual bool GetOrigin(
59 int process_id,
60 int render_frame_id,
61 std::string* origin) const override {
62 if (process_id == kInstantRendererPID) {
63 *origin = kInstantOrigin;
64 return true;
66 if (process_id == kNonInstantRendererPID) {
67 *origin = kNonInstantOrigin;
68 return true;
70 return false;
74 class IframeSourceTest : public testing::Test {
75 public:
76 // net::URLRequest wants to be executed with a message loop that has TYPE_IO.
77 // InstantIOContext needs to be created on the UI thread and have everything
78 // else happen on the IO thread. This setup is a hacky way to satisfy all
79 // those constraints.
80 IframeSourceTest()
81 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
82 resource_context_(&test_url_request_context_),
83 instant_io_context_(NULL),
84 response_(NULL) {
87 TestIframeSource* source() { return source_.get(); }
89 std::string response_string() {
90 if (response_.get()) {
91 return std::string(response_->front_as<char>(), response_->size());
93 return "";
96 scoped_ptr<net::URLRequest> MockRequest(
97 const std::string& url,
98 bool allocate_info,
99 int render_process_id,
100 int render_frame_id) {
101 scoped_ptr<net::URLRequest> request(
102 resource_context_.GetRequestContext()->CreateRequest(
103 GURL(url),
104 net::DEFAULT_PRIORITY,
105 NULL,
106 NULL));
107 if (allocate_info) {
108 content::ResourceRequestInfo::AllocateForTesting(
109 request.get(),
110 content::RESOURCE_TYPE_SUB_FRAME,
111 &resource_context_,
112 render_process_id,
113 render_frame_id,
114 MSG_ROUTING_NONE,
115 false);
117 return request.Pass();
120 void SendResource(int resource_id) {
121 source()->SendResource(resource_id, callback_);
124 void SendJSWithOrigin(
125 int resource_id,
126 int render_process_id,
127 int render_frame_id) {
128 source()->SendJSWithOrigin(resource_id, render_process_id, render_frame_id,
129 callback_);
132 private:
133 virtual void SetUp() override {
134 source_.reset(new TestIframeSource());
135 callback_ = base::Bind(&IframeSourceTest::SaveResponse,
136 base::Unretained(this));
137 instant_io_context_ = new InstantIOContext;
138 InstantIOContext::SetUserDataOnIO(&resource_context_, instant_io_context_);
139 InstantIOContext::AddInstantProcessOnIO(instant_io_context_,
140 kInstantRendererPID);
141 response_ = NULL;
144 virtual void TearDown() {
145 source_.reset();
148 void SaveResponse(base::RefCountedMemory* data) {
149 response_ = data;
152 content::TestBrowserThreadBundle thread_bundle_;
154 net::TestURLRequestContext test_url_request_context_;
155 content::MockResourceContext resource_context_;
156 scoped_ptr<TestIframeSource> source_;
157 content::URLDataSource::GotDataCallback callback_;
158 scoped_refptr<InstantIOContext> instant_io_context_;
159 scoped_refptr<base::RefCountedMemory> response_;
162 TEST_F(IframeSourceTest, ShouldServiceRequest) {
163 scoped_ptr<net::URLRequest> request;
164 request = MockRequest("http://test/loader.js", true,
165 kNonInstantRendererPID, 0);
166 EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
167 request = MockRequest("chrome-search://bogus/valid.js", true,
168 kInstantRendererPID, 0);
169 EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
170 request = MockRequest("chrome-search://test/bogus.js", true,
171 kInstantRendererPID, 0);
172 EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
173 request = MockRequest("chrome-search://test/valid.js", true,
174 kInstantRendererPID, 0);
175 EXPECT_TRUE(source()->ShouldServiceRequest(request.get()));
176 request = MockRequest("chrome-search://test/valid.js", true,
177 kNonInstantRendererPID, 0);
178 EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
179 request = MockRequest("chrome-search://test/valid.js", true,
180 kInvalidRendererPID, 0);
181 EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
184 TEST_F(IframeSourceTest, GetMimeType) {
185 // URLDataManagerBackend does not include / in path_and_query.
186 EXPECT_EQ("text/html", source()->GetMimeType("foo.html"));
187 EXPECT_EQ("application/javascript", source()->GetMimeType("foo.js"));
188 EXPECT_EQ("text/css", source()->GetMimeType("foo.css"));
189 EXPECT_EQ("image/png", source()->GetMimeType("foo.png"));
190 EXPECT_EQ("", source()->GetMimeType("bogus"));
193 TEST_F(IframeSourceTest, SendResource) {
194 SendResource(IDR_MOST_VISITED_TITLE_HTML);
195 EXPECT_FALSE(response_string().empty());
198 TEST_F(IframeSourceTest, SendJSWithOrigin) {
199 SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kInstantRendererPID, 0);
200 EXPECT_FALSE(response_string().empty());
201 SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kNonInstantRendererPID, 0);
202 EXPECT_FALSE(response_string().empty());
203 SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kInvalidRendererPID, 0);
204 EXPECT_TRUE(response_string().empty());