Make castv2 performance test work.
[chromium-blink-merge.git] / chrome / service / cloud_print / cloud_print_url_fetcher_unittest.cc
blob60e03780c554c50449c0bcd664d13d6f9cdc9bc7
1 // Copyright (c) 2012 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 "base/command_line.h"
6 #include "base/memory/ref_counted.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/thread.h"
10 #include "base/values.h"
11 #include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
12 #include "chrome/service/service_process.h"
13 #include "net/test/spawned_test_server/spawned_test_server.h"
14 #include "net/url_request/url_request_context_getter.h"
15 #include "net/url_request/url_request_status.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "net/url_request/url_request_throttler_manager.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "url/gurl.h"
21 using base::Time;
22 using base::TimeDelta;
24 namespace cloud_print {
26 const base::FilePath::CharType kDocRoot[] =
27 FILE_PATH_LITERAL("chrome/test/data");
29 int g_request_context_getter_instances = 0;
30 class TrackingTestURLRequestContextGetter
31 : public net::TestURLRequestContextGetter {
32 public:
33 explicit TrackingTestURLRequestContextGetter(
34 base::MessageLoopProxy* io_message_loop_proxy,
35 net::URLRequestThrottlerManager* throttler_manager)
36 : TestURLRequestContextGetter(io_message_loop_proxy),
37 throttler_manager_(throttler_manager) {
38 g_request_context_getter_instances++;
41 net::TestURLRequestContext* GetURLRequestContext() override {
42 if (!context_.get()) {
43 context_.reset(new net::TestURLRequestContext(true));
44 context_->set_throttler_manager(throttler_manager_);
45 context_->Init();
47 return context_.get();
50 protected:
51 ~TrackingTestURLRequestContextGetter() override {
52 g_request_context_getter_instances--;
55 private:
56 // Not owned here.
57 net::URLRequestThrottlerManager* throttler_manager_;
58 scoped_ptr<net::TestURLRequestContext> context_;
61 class TestCloudPrintURLFetcher : public CloudPrintURLFetcher {
62 public:
63 explicit TestCloudPrintURLFetcher(
64 base::MessageLoopProxy* io_message_loop_proxy)
65 : io_message_loop_proxy_(io_message_loop_proxy) {
68 net::URLRequestContextGetter* GetRequestContextGetter() override {
69 return new TrackingTestURLRequestContextGetter(
70 io_message_loop_proxy_.get(), throttler_manager());
73 net::URLRequestThrottlerManager* throttler_manager() {
74 return &throttler_manager_;
77 private:
78 ~TestCloudPrintURLFetcher() override {}
80 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
82 // We set this as the throttler manager for the
83 // TestURLRequestContext we create.
84 net::URLRequestThrottlerManager throttler_manager_;
87 class CloudPrintURLFetcherTest : public testing::Test,
88 public CloudPrintURLFetcherDelegate {
89 public:
90 CloudPrintURLFetcherTest() : max_retries_(0), fetcher_(NULL) { }
92 // Creates a URLFetcher, using the program's main thread to do IO.
93 virtual void CreateFetcher(const GURL& url, int max_retries);
95 // CloudPrintURLFetcher::Delegate
96 CloudPrintURLFetcher::ResponseAction HandleRawResponse(
97 const net::URLFetcher* source,
98 const GURL& url,
99 const net::URLRequestStatus& status,
100 int response_code,
101 const net::ResponseCookies& cookies,
102 const std::string& data) override;
104 CloudPrintURLFetcher::ResponseAction OnRequestAuthError() override {
105 ADD_FAILURE();
106 return CloudPrintURLFetcher::STOP_PROCESSING;
109 std::string GetAuthHeader() override { return std::string(); }
111 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
112 return io_message_loop_proxy_;
115 protected:
116 void SetUp() override {
117 testing::Test::SetUp();
119 io_message_loop_proxy_ = base::MessageLoopProxy::current();
122 void TearDown() override {
123 fetcher_ = NULL;
124 // Deleting the fetcher causes a task to be posted to the IO thread to
125 // release references to the URLRequestContextGetter. We need to run all
126 // pending tasks to execute that (this is the IO thread).
127 base::MessageLoop::current()->RunUntilIdle();
128 EXPECT_EQ(0, g_request_context_getter_instances);
131 // URLFetcher is designed to run on the main UI thread, but in our tests
132 // we assume that the current thread is the IO thread where the URLFetcher
133 // dispatches its requests to. When we wish to simulate being used from
134 // a UI thread, we dispatch a worker thread to do so.
135 base::MessageLoopForIO io_loop_;
136 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
137 int max_retries_;
138 Time start_time_;
139 scoped_refptr<TestCloudPrintURLFetcher> fetcher_;
142 class CloudPrintURLFetcherBasicTest : public CloudPrintURLFetcherTest {
143 public:
144 CloudPrintURLFetcherBasicTest()
145 : handle_raw_response_(false), handle_raw_data_(false) { }
146 // CloudPrintURLFetcher::Delegate
147 CloudPrintURLFetcher::ResponseAction HandleRawResponse(
148 const net::URLFetcher* source,
149 const GURL& url,
150 const net::URLRequestStatus& status,
151 int response_code,
152 const net::ResponseCookies& cookies,
153 const std::string& data) override;
155 CloudPrintURLFetcher::ResponseAction HandleRawData(
156 const net::URLFetcher* source,
157 const GURL& url,
158 const std::string& data) override;
160 CloudPrintURLFetcher::ResponseAction HandleJSONData(
161 const net::URLFetcher* source,
162 const GURL& url,
163 base::DictionaryValue* json_data,
164 bool succeeded) override;
166 void SetHandleRawResponse(bool handle_raw_response) {
167 handle_raw_response_ = handle_raw_response;
169 void SetHandleRawData(bool handle_raw_data) {
170 handle_raw_data_ = handle_raw_data;
172 private:
173 bool handle_raw_response_;
174 bool handle_raw_data_;
177 // Version of CloudPrintURLFetcherTest that tests overload protection.
178 class CloudPrintURLFetcherOverloadTest : public CloudPrintURLFetcherTest {
179 public:
180 CloudPrintURLFetcherOverloadTest() : response_count_(0) {
183 // CloudPrintURLFetcher::Delegate
184 CloudPrintURLFetcher::ResponseAction HandleRawData(
185 const net::URLFetcher* source,
186 const GURL& url,
187 const std::string& data) override;
189 private:
190 int response_count_;
193 // Version of CloudPrintURLFetcherTest that tests backoff protection.
194 class CloudPrintURLFetcherRetryBackoffTest : public CloudPrintURLFetcherTest {
195 public:
196 CloudPrintURLFetcherRetryBackoffTest() : response_count_(0) {
199 // CloudPrintURLFetcher::Delegate
200 CloudPrintURLFetcher::ResponseAction HandleRawData(
201 const net::URLFetcher* source,
202 const GURL& url,
203 const std::string& data) override;
205 void OnRequestGiveUp() override;
207 private:
208 int response_count_;
212 void CloudPrintURLFetcherTest::CreateFetcher(const GURL& url, int max_retries) {
213 fetcher_ = new TestCloudPrintURLFetcher(io_message_loop_proxy().get());
215 // Registers an entry for test url. It only allows 3 requests to be sent
216 // in 200 milliseconds.
217 scoped_refptr<net::URLRequestThrottlerEntry>
218 entry(new net::URLRequestThrottlerEntry(
219 fetcher_->throttler_manager(), std::string(), 200, 3, 1, 2.0, 0.0, 256));
220 fetcher_->throttler_manager()->OverrideEntryForTests(url, entry.get());
222 max_retries_ = max_retries;
223 start_time_ = Time::Now();
224 fetcher_->StartGetRequest(CloudPrintURLFetcher::REQUEST_MAX, url, this,
225 max_retries_, std::string());
228 CloudPrintURLFetcher::ResponseAction
229 CloudPrintURLFetcherTest::HandleRawResponse(
230 const net::URLFetcher* source,
231 const GURL& url,
232 const net::URLRequestStatus& status,
233 int response_code,
234 const net::ResponseCookies& cookies,
235 const std::string& data) {
236 EXPECT_TRUE(status.is_success());
237 EXPECT_EQ(200, response_code); // HTTP OK
238 EXPECT_FALSE(data.empty());
239 return CloudPrintURLFetcher::CONTINUE_PROCESSING;
242 CloudPrintURLFetcher::ResponseAction
243 CloudPrintURLFetcherBasicTest::HandleRawResponse(
244 const net::URLFetcher* source,
245 const GURL& url,
246 const net::URLRequestStatus& status,
247 int response_code,
248 const net::ResponseCookies& cookies,
249 const std::string& data) {
250 EXPECT_TRUE(status.is_success());
251 EXPECT_EQ(200, response_code); // HTTP OK
252 EXPECT_FALSE(data.empty());
254 if (handle_raw_response_) {
255 // If the current message loop is not the IO loop, it will be shut down when
256 // the main loop returns and this thread subsequently goes out of scope.
257 io_message_loop_proxy()->PostTask(FROM_HERE,
258 base::MessageLoop::QuitClosure());
259 return CloudPrintURLFetcher::STOP_PROCESSING;
261 return CloudPrintURLFetcher::CONTINUE_PROCESSING;
264 CloudPrintURLFetcher::ResponseAction
265 CloudPrintURLFetcherBasicTest::HandleRawData(
266 const net::URLFetcher* source,
267 const GURL& url,
268 const std::string& data) {
269 // We should never get here if we returned true in HandleRawResponse
270 EXPECT_FALSE(handle_raw_response_);
271 if (handle_raw_data_) {
272 io_message_loop_proxy()->PostTask(FROM_HERE,
273 base::MessageLoop::QuitClosure());
274 return CloudPrintURLFetcher::STOP_PROCESSING;
276 return CloudPrintURLFetcher::CONTINUE_PROCESSING;
279 CloudPrintURLFetcher::ResponseAction
280 CloudPrintURLFetcherBasicTest::HandleJSONData(
281 const net::URLFetcher* source,
282 const GURL& url,
283 base::DictionaryValue* json_data,
284 bool succeeded) {
285 // We should never get here if we returned true in one of the above methods.
286 EXPECT_FALSE(handle_raw_response_);
287 EXPECT_FALSE(handle_raw_data_);
288 io_message_loop_proxy()->PostTask(FROM_HERE,
289 base::MessageLoop::QuitClosure());
290 return CloudPrintURLFetcher::STOP_PROCESSING;
293 CloudPrintURLFetcher::ResponseAction
294 CloudPrintURLFetcherOverloadTest::HandleRawData(
295 const net::URLFetcher* source,
296 const GURL& url,
297 const std::string& data) {
298 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
299 response_count_++;
300 if (response_count_ < 20) {
301 fetcher_->StartGetRequest(CloudPrintURLFetcher::REQUEST_MAX, url, this,
302 max_retries_, std::string());
303 } else {
304 // We have already sent 20 requests continuously. And we expect that
305 // it takes more than 1 second due to the overload protection settings.
306 EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
307 io_message_loop_proxy()->PostTask(FROM_HERE,
308 base::MessageLoop::QuitClosure());
310 return CloudPrintURLFetcher::STOP_PROCESSING;
313 CloudPrintURLFetcher::ResponseAction
314 CloudPrintURLFetcherRetryBackoffTest::HandleRawData(
315 const net::URLFetcher* source,
316 const GURL& url,
317 const std::string& data) {
318 response_count_++;
319 // First attempt + 11 retries = 12 total responses.
320 EXPECT_LE(response_count_, 12);
321 return CloudPrintURLFetcher::RETRY_REQUEST;
324 void CloudPrintURLFetcherRetryBackoffTest::OnRequestGiveUp() {
325 // It takes more than 200 ms to finish all 11 requests.
326 EXPECT_TRUE(Time::Now() - start_time_ >= TimeDelta::FromMilliseconds(200));
327 io_message_loop_proxy()->PostTask(FROM_HERE,
328 base::MessageLoop::QuitClosure());
331 TEST_F(CloudPrintURLFetcherBasicTest, HandleRawResponse) {
332 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
333 net::SpawnedTestServer::kLocalhost,
334 base::FilePath(kDocRoot));
335 ASSERT_TRUE(test_server.Start());
336 SetHandleRawResponse(true);
338 CreateFetcher(test_server.GetURL("echo"), 0);
339 base::MessageLoop::current()->Run();
342 TEST_F(CloudPrintURLFetcherBasicTest, HandleRawData) {
343 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
344 net::SpawnedTestServer::kLocalhost,
345 base::FilePath(kDocRoot));
346 ASSERT_TRUE(test_server.Start());
348 SetHandleRawData(true);
349 CreateFetcher(test_server.GetURL("echo"), 0);
350 base::MessageLoop::current()->Run();
353 TEST_F(CloudPrintURLFetcherOverloadTest, Protect) {
354 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
355 net::SpawnedTestServer::kLocalhost,
356 base::FilePath(kDocRoot));
357 ASSERT_TRUE(test_server.Start());
359 GURL url(test_server.GetURL("defaultresponse"));
360 CreateFetcher(url, 11);
362 base::MessageLoop::current()->Run();
365 TEST_F(CloudPrintURLFetcherRetryBackoffTest, GiveUp) {
366 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
367 net::SpawnedTestServer::kLocalhost,
368 base::FilePath(kDocRoot));
369 ASSERT_TRUE(test_server.Start());
371 GURL url(test_server.GetURL("defaultresponse"));
372 CreateFetcher(url, 11);
374 base::MessageLoop::current()->Run();
377 } // namespace cloud_print